Skip to content

Permanently delete never-paid VMs + super-admin VM purge - #176

Merged
v0l merged 3 commits into
masterfrom
feat/perma-delete-vms-168
Jul 20, 2026
Merged

Permanently delete never-paid VMs + super-admin VM purge#176
v0l merged 3 commits into
masterfrom
feat/perma-delete-vms-168

Conversation

@v0l

@v0l v0l commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #168

Summary

VMs that have never been paid (their subscription was never set up) are now hard-deleted from the database instead of soft-deleted, both when an admin deletes them and in the worker's hourly unpaid-VM cleanup. Nothing is left behind.

Additionally, super_admins can permanently purge any VM (including ones with payment history) via a new purge flag on the delete endpoint — intended for clearing out test VMs.

Changes

  • LNVpsDb::hard_delete_vm(vm_id) (mysql + mock) — removes the VM row plus every related record in one transaction: vm_history, vm_firewall_rule, vm_ip_assignment, and the VM's own subscription (+ cascaded subscription_line_item) and its subscription_payment history (payments deleted first, since they lack ON DELETE CASCADE).
  • WorkJob::DeleteVm gains a purge flag. The worker computes hard_delete = purge || !ever_paid and skips vm_history logging on hard delete (the row is gone → would break the FK).
  • provisioner.delete_vm(vm_id, purge) picks hard vs soft delete.
  • DELETE /api/admin/v1/vms/{id} accepts optional purge: true, gated to the super_admin role via new AdminAuth::is_super_admin (checked before the VM lookup, so non-super-admins get 403).
  • Worker unpaid-cleanup now purges never-paid VMs.

Tests

  • test_hard_delete_vm_purges_related_records (mock DB) — full cleanup
  • test_delete_vm_purge_removes_vm_row (provisioner) — purge removes VM row & hard-deletes IPs
  • Updated two worker unpaid-cleanup tests to assert the row is purged
  • test_vm_manager_cannot_purge_vm (e2e RBAC) — non-super-admin purge → 403, plus new delete_auth_body client helper

Docs

  • API_CHANGELOG.md and ADMIN_API_ENDPOINTS.md updated for the purge flag / new behaviour

All builds pass (cargo build --workspace), formatting is clean, and unit tests pass for lnvps_db, lnvps_api, lnvps_api_admin, and lnvps_api_common. The mysql hard_delete_vm and admin endpoint are additionally covered by the e2e suite.

v0l added 3 commits July 20, 2026 11:41
Never-paid (new) VMs are now hard-deleted from the database instead of
soft-deleted, both in the worker's unpaid-VM cleanup and in admin deletes.
Adds a super_admin-only `purge` flag to DELETE /api/admin/v1/vms/{id} to
permanently delete any VM (including ones with payment history), clearing
up all related entities.

- New LNVpsDb::hard_delete_vm removes the VM plus vm_history, vm_firewall_rule,
  vm_ip_assignment, and the VM's subscription (line items + payment history)
- WorkJob::DeleteVm gains a purge flag; worker skips vm_history logging on
  hard delete (the row is gone)
- AdminAuth::is_super_admin gates the purge flag (403 for non-super-admins)
- Tests: mock + provisioner purge coverage, updated worker cleanup asserts,
  e2e RBAC purge-forbidden test + delete_auth_body helper
- Docs: API_CHANGELOG.md + ADMIN_API_ENDPOINTS.md

Fixes #168
The vm_payment table was dropped by migration 20260716130000; delete_user
still tried to `delete from vm_payment`, failing with 'Table lnvps.vm_payment
doesn't exist'. Payment rows are removed via subscription_payment lower in
the same transaction.
@v0l
v0l force-pushed the feat/perma-delete-vms-168 branch from da4970d to 0a1a63f Compare July 20, 2026 10:45
@v0l
v0l merged commit d13b0ce into master Jul 20, 2026
8 checks passed
@v0l
v0l deleted the feat/perma-delete-vms-168 branch July 20, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perma delete never paid (new) vms

1 participant