{% load i18n %} {# Why a device the plugin created refuses a manual delete, and where the #} {# supported delete lives. NetBox's own delete dialog renders the raw #} {# ProtectedError - our table names and nothing else - so the explanation #} {# has to be on the page the operator is already looking at. #}
| {% trans "Owned by sync" %} | {% for sync in ownership.syncs %} {{ sync.name }}{% if not forloop.last %}, {% endif %} {% empty %} — {% endfor %} |
|---|---|
| {% trans "Scope status" %} | {% if ownership.uncovered %} {% trans "Uncovered" %} {% endif %} {% if ownership.out_of_scope %} {% trans "Out of scope" %} {% endif %} {% if ownership.backfilled %} {% trans "Backfilled" %} {% endif %} {% if not ownership.uncovered and not ownership.out_of_scope and not ownership.backfilled %} {% trans "In scope" %} {% endif %} |
| {% trans "Absent from Forward for" %} | {% blocktrans count runs=ownership.absence.consecutive_absent_runs trimmed %} {{ runs }} consecutive run {% plural %} {{ runs }} consecutive runs {% endblocktrans %} ({% trans "since" %} {{ ownership.absence.first_absent_at }}) |
| {% trans "Records held" %} |
{% for label, count in ownership.holders %}
{{ label }}: {{ count }}{% if not forloop.last %} {% endif %} {% empty %} {% trans "None" %} {% endfor %} |
| {% trans "Would refuse a delete" %} |
{# The database's own verdict, so it includes rows from other #}
{# plugins reached through the cascade - BGP peers attached to this #}
{# device's IP addresses, for instance - not only our records. #}
{% for label, count in ownership.delete_blockers %}
{{ label }} × {{ count }}{% if not forloop.last %}{% endif %} {% endfor %} |
{% blocktrans trimmed with reason=ownership.prune.endpoint_detail_label %} Forward still reports this device as an SNMP endpoint, but the endpoint scope excludes it: {{ reason }}. That is a scoping decision, not a removal, so the uncovered cleanup will never delete it. {% endblocktrans %} {% if ownership.prune.endpoint_detail == "endpoint_untagged" %} {% trans "Add one of the endpoint's Forward tags to the sync's include tags, or tag the endpoint in Forward, to cover it again." %} {% elif ownership.prune.endpoint_detail == "endpoint_generic" %} {% trans "Enable generic endpoint import on the source to cover it again, or delete it by hand if it should not have been imported." %} {% elif ownership.prune.endpoint_detail == "endpoint_scope_off" %} {% trans "Enable endpoint import on the source to cover it again." %} {% elif ownership.prune.endpoint_detail == "endpoint_cimc" %} {% trans "CIMC controllers are imported as inventory items of their server; this standalone device predates that and can be deleted by hand." %} {% elif ownership.prune.endpoint_detail == "endpoint_no_snmp" %} {% trans "Restore SNMP collection for the endpoint in Forward to cover it again." %} {% endif %}
{% elif ownership.prune.still_reported %}{% blocktrans trimmed %} Forward still reports this device; it carries none of this sync's include tags. That is a scoping decision, not a removal, so the uncovered cleanup will never delete it. Change the tags in Forward or the sync's include tags to bring it back into scope. {% endblocktrans %}
{% endif %} {% if ownership.prune.absent_detail %} {# The snapshot has no such device, but Forward's configuration still #} {# lists it under an include tag - which is what the Forward UI shows, #} {# and why an operator reads this as "tagged in Forward, not synced". #}{% blocktrans trimmed with reason=ownership.prune.absent_detail_label %} Forward's device configuration still shows it: {{ reason }}. The sync reads the snapshot, so a device the snapshot does not carry cannot be tagged or updated in NetBox however it is tagged in Forward. {% endblocktrans %} {% if ownership.prune.absent_detail == "absent_configured_disabled" %} {% trans "Re-enable collection for the device in Forward to cover it again, or remove it here if the disable is permanent." %} {% elif ownership.prune.absent_detail == "absent_configured_uncollected" %} {% trans "Check the device's collection status in Forward; once a snapshot carries it again the sync covers it automatically." %} {% elif ownership.prune.absent_detail == "absent_tag_only" %} {% trans "The tag entry outlived the device: a vsys or vdom child the snapshot no longer models, or a device removed from collection without clearing its tags." %} {% endif %}
{% endif %} {% if ownership.holders %}{% blocktrans trimmed %} Deleting this device from NetBox, here or from the device list, also removes these Forward records; the next sync will not look for it. The scope reconciliation panel on the owning sync is the gated way: it deletes only devices Forward no longer reports, applies the absence quarantine and the shrink refusal, and records what it removed. {% endblocktrans %}
{% endif %} {% if ownership.foreign_delete_blockers %} {# Be exact about the limit: the prune releases OUR rows and then asks #} {# the database to delete the device. A row another plugin holds it with #} {# is reported, not removed, so the prune refuses this device too until #} {# that row is gone. Promising otherwise would send an operator to a #} {# button that cannot help them, so this says what to do instead. #}{% blocktrans trimmed %} Some of the records holding this device belong to another plugin, not to Forward. Scope reconciliation releases only its own, so it will refuse this device too and report which model refused it. {% endblocktrans %}
{% if ownership.release_blockers.offered and perms.dcim.delete_device %}{% blocktrans trimmed %} These are all rows this plugin's own routing integration re-syncs from Forward, so releasing them costs nothing the next sync does not restore. Releasing deletes exactly the rows named below - nothing else, and never the device itself. {% endblocktrans %}
{% trans "Once released, delete the device here or from Prune uncovered devices on the owning sync." %}
{% else %}{% trans "To delete this device:" %}
{{ label }} × {{ count }}{% if not forloop.last %}, {% endif %}{% endfor %}
{% blocktrans trimmed %} Records derived from Forward data are recreated by the next sync, so deleting them is not a permanent loss. Anything you created by hand is not — check before deleting. If you would rather we confirm which is which, download the support bundle from the sync page and send it: it carries these blockers and the counts behind them. {% endblocktrans %}
{% endif %}