{% 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 "Forward Ownership" %}
{% if ownership.absence %} {% endif %} {% if ownership.delete_blockers %} {% endif %}
{% 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 manual 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 %}
{# The remedy for this one device, when the whole-set prune would take it #} {# anyway. The button narrows that prune rather than deleting directly, so #} {# every gate still applies and the job records a reason if it declines. #} {% if ownership.prune.offered and perms.dcim.delete_device %}
{% csrf_token %} {% if ownership.prune.held %}
{% endif %} {% if ownership.prune.held %}

{% blocktrans with runs=ownership.prune.required_runs hours=ownership.prune.required_hours %}Forward no longer reports this device, but a device disabled in Forward looks exactly the same, so the absence must persist for {{ runs }} consecutive syncs and {{ hours }} hours before the prune will delete it.{% endblocktrans %}

{% endif %}
{% elif ownership.prune.still_reported and ownership.prune.endpoint_detail %}

{% 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.holders %}

{% blocktrans trimmed %} NetBox will refuse a manual delete of this device while these records exist, and its dialog reports only the record names. Deleting it here would also strand the ownership evidence the next sync reads. Use the scope reconciliation panel on the owning sync instead: it releases ownership first, 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. #} {% endif %}
{% if ownership.primary_sync_url %} {% endif %}