Skip to content

[change] Prevent deleting subnet division rules used by device configurations #1434

Description

@nemesifier

Problem
Deleting a SubnetDivisionRule that is currently used by device configurations is allowed, but this removes the generated subnet/IP context that those configurations may depend on.

When this happens, affected device configurations can remain marked as applied even though the rendered configuration would change or contain unresolved subnet division variables such as {{ OW_subnet1 }} or {{ OW_subnet1_ip1 }}.

This is unsafe because OpenWISP cannot automatically determine how to clean up the user-authored objects that depend on the rule. The dependency may be in templates, VPN templates, group templates, default/required templates, or device-specific configuration. Automatically deleting templates, unassigning templates from devices, or rewriting template contents would be surprising and could remove unrelated configuration.

The safe behavior is to prevent deleting subnet division rules while they are used by device configurations, and provide links/filters that help users find the affected devices so they can clean up the dependency manually before retrying deletion.

Steps To Reproduce
Steps to reproduce the behavior:

  1. Create a subnet division rule for a VPN master subnet.
  2. Create or use a device configuration that references one of the variables generated by the rule, for example {{ OW_subnet1 }}.
  3. Apply the configuration so its status is applied.
  4. Delete the SubnetDivisionRule.
  5. Refresh the affected configuration.

Desired behavior
Deleting a SubnetDivisionRule that is still used by device configurations should be prevented.

The model-level deletion path should enforce this rule too, not only the admin. This keeps behavior consistent if deletion is attempted from Python code, management commands, tests, bulk deletion, or future API endpoints.

The admin deletion confirmation page should show a clear error explaining that the rule is still in use. Instead of embedding an unbounded list of affected devices, it should link to a filtered device changelist that shows devices using the subnet division rule.

The REST API, if/when subnet division rules are exposed there, should reject deletion with a structured response and link to, or point clients to, a filterable devices endpoint. The response should not include the full affected device list because large deployments need pagination. It should include a stable error code and enough information for API clients to retrieve affected devices through a paginated endpoint.

Example response:

{
  "detail": "This subnet division rule is used by device configurations and cannot be deleted.",
  "code": "subnet_division_rule_in_use",
  "affected_devices_url": "/api/v1/controller/device/?subnet_division_rule=<rule-id>"
}

This likely requires adding a device admin filter and a REST API filter for devices using a specific subnet division rule. Related context: #599 already tracks the broader need to easily find devices linked to generated IP addresses and subnets, including via API.

Deleting an unused SubnetDivisionRule should remain possible and should keep the existing cleanup behavior for generated subnets/IPs.

No config checksum/cache invalidation should be needed when deletion is allowed, because successful deletion should imply no device configuration is using the rule anymore. If a rule is still used by any config, deletion should be blocked instead of allowed and followed by cache invalidation.

Actual behavior
The rule is deleted and the generated subnets/IPs are removed, but affected configurations are not protected from the deletion. Configurations can remain marked as applied with stale checksum_db even though their subnet division context has disappeared.

A regression test demonstrating the current behavior fails with:

AssertionError: 'applied' != 'modified'
- applied
+ modified

The failing test shows the current data integrity issue, but the desired fix is not to invalidate the checksum after deletion. The desired fix is to block deletion while any device configuration is using the rule, then allow deletion only once the user has removed the dependency manually.

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    No fields configured for Task.

    Projects

    Status
    To do
    Status
    To do (Python & Django)
    Status
    To do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions