{% extends 'generic/object.html' %} {% load helpers %} {% load plugins %} {% load i18n %} {% block content %}
{% trans "Health Summary" %}
{% trans "Export Live Source Check" %} {% trans "Export source reachability diagnostics." %}
{% trans "Audits" %} {% trans "Read-only checks behind a symptom: primary-IP resolution, stale IPAM and hardware notices, identity churn, ambiguous names, dangling routing rows, interface VLANs, APIC readiness, fast-baseline eligibility." %}
{% trans "Source" %} {{ health.source.name }}
{% trans "Source status" %} {{ health.source.status }}
{% trans "Source URL" %} {{ health.source.url }}
{% trans "Branching available" %} {{ health.runtime.branching_available|yesno:"Yes,No" }}
{% trans "Max changes per staging item" %} {{ health.runtime.max_changes_per_staging_item }}
{% trans "Forward API timeout" %} {{ health.runtime.source_timeout_seconds|placeholder }}
{% trans "Worker timeout" %} {{ health.runtime.rq_default_timeout_seconds|placeholder }}
{% trans "Pushdown alert thresholds" %} {% with thresholds=health.runtime.pushdown_alert_thresholds %} fallback={{ thresholds.fallback_warn_rate|placeholder }}, runtime={{ thresholds.runtime_fallback_warn_share|placeholder }}, diff={{ thresholds.diff_warn_ratio|placeholder }} {% endwith %}
{% trans "Snapshot selection" %} {{ health.runtime.snapshot_selector|placeholder }}
{% trans "Next run" %}
{{ health.next_run.message }}
{% if health.next_run.blockers %}
    {% for blocker in health.next_run.blockers %}
  • {{ blocker.message }}
  • {% endfor %}
{% endif %}
{% trans "Forward API Usage" %}
{% if health.api_usage.available %} {% with budget=health.api_usage.budget counters=health.api_usage.counters metrics=health.api_usage.budget.metrics %} {% if budget.warnings %} {% endif %} {% if budget.failure_reasons %} {% endif %}
{% trans "Budget status" %} {% if budget.status == "passed" %} {% trans "Pass" %} {% elif budget.status == "failed" %} {% trans "Fail" %} {% elif budget.status == "warning" %} {% trans "Warn" %} {% else %} {{ budget.status|placeholder }} {% endif %}
{% trans "Configured rate" %} {{ metrics.configured_requests_per_minute|placeholder }} / {{ metrics.hard_block_requests_per_minute|placeholder }} rpm
{% trans "Observed rate" %} {{ metrics.observed_http_attempts_per_minute|placeholder }} rpm {% if metrics.observed_rate_sample_complete %} ({% trans "sampled" %}) {% endif %}
{% trans "HTTP attempts" %} {{ counters.http_attempts|placeholder }}
{% trans "HTTP 429 failures" %} {{ counters.http_429_failures|placeholder }}
{% trans "NQE calls" %} query={{ counters.nqe_query_calls|placeholder }}, diff={{ counters.nqe_diff_calls|placeholder }}, unique={{ counters.nqe_execution_signature_count|placeholder }}, repeated={{ counters.nqe_repeated_execution_count|placeholder }}, pages={{ counters.nqe_pages|placeholder }}
{% trans "Throttle sleep" %} {{ metrics.throttle_sleep_seconds|placeholder }} s
{% trans "Query parameters" %} {% with param_summary=health.api_usage.step_query_parameters %} {% if param_summary.available %} {{ param_summary.step_count }} {% trans "step(s) with explicit parameters" %}
    {% for item in param_summary.top_steps %}
  • {{ item.model }} / {{ item.query_name }}: {{ item.query_parameters }}
  • {% endfor %}
{% else %} {% trans "No explicit step query parameters recorded." %} {% endif %} {% endwith %}
{% trans "Warnings" %} {{ budget.warnings }}
{% trans "Failure reasons" %} {{ budget.failure_reasons }}
{% endwith %} {% else %}

{% trans "No stored Forward API usage evidence is available for the latest ingestion." %}

{% endif %}
{% trans "Dependency Lookup Cache" %}
{% if health.dependency_lookup_cache.available %}
{% trans "Models primed" %} {{ health.dependency_lookup_cache.model_count|placeholder }}
{% trans "Rows processed" %} {{ health.dependency_lookup_cache.row_count|placeholder }}
{% trans "Primed targets" %} {{ health.dependency_lookup_cache.primed_target_count|placeholder }}
{% if health.dependency_lookup_cache.models %}
{% trans "Top primed models" %}
    {% for item in health.dependency_lookup_cache.models %}
  • {{ item.model }}: {{ item.row_count }} {% trans "rows" %}, {{ item.primed_target_count }} {% trans "primed targets" %} {% if item.fhrp_group_count %} , {{ item.fhrp_group_count }} {% trans "FHRP groups" %} {% endif %}
  • {% endfor %}
{% endif %} {% else %}

{% trans "No dependency lookup cache evidence is available for the latest ingestion." %}

{% endif %}
{% trans "Optional Plugin Capabilities" %}
{% for integration_key, integration in health.optional_plugin_capabilities_ui.items %}
{{ integration.display_name|default:integration_key }}
{% trans "Integration" %} {{ integration.app_label|placeholder }}
{% trans "Installed" %} {{ integration.installed|yesno:"Yes,No" }}
{% trans "Installed version" %} {{ integration.version|placeholder }}
{% trans "Required version" %} {{ integration.required_version|placeholder }}
{% trans "Package" %} {{ integration.package_name|placeholder }}
{% trans "Available" %} {{ integration.available|yesno:"Yes,No" }}
{% trans "Availability status" %} {{ integration.availability_status|placeholder }}
{% trans "Availability reason" %} {{ integration.availability_reason|placeholder }}
{% trans "Version matches" %} {{ integration.version_matches|yesno:"Yes,No" }}
{% trans "Required models missing" %} {{ integration.missing_required|length }}
{% trans "Command inventory entries" %} {{ integration.command_inventory_count }}
{% if integration.missing_required %}
{% trans "Missing required models" %}
    {% for model in integration.missing_required %}
  • {{ model }}
  • {% endfor %}
{% endif %} {% if integration.command_inventory %}
{% trans "Command inventory" %}
    {% for command in integration.command_inventory %}
  • {{ command.command_type }} - {{ command.status|default:"unknown" }} {% if command.source %} - {{ command.source }} {% endif %}
  • {% endfor %}
{% endif %}
{% empty %}

{% trans "No optional plugin capability evidence is available." %}

{% endfor %}
{% trans "Checks" %}
{% for check in health.checks %} {% empty %} {% endfor %}
{% trans "Check" %} {% trans "Status" %} {% trans "Message" %}
{{ check.name }} {% if check.status == "pass" %} {% trans "Pass" %} {% elif check.status == "fail" %} {% trans "Fail" %} {% elif check.status == "warn" %} {% trans "Warn" %} {% else %} {% trans "Info" %} {% endif %} {{ check.message }} {% if check.url %}{{ check.url_label|default:_("Open") }}{% endif %}
{% trans "No checks available" %}
{% plugin_left_page object %}
{% trans "Query Binding" %}
{% trans "Raw query maps" %} {{ health.query_modes.query }}
{% trans "Direct query ID maps" %} {{ health.query_modes.query_id }}
{% trans "Repository path maps" %} {{ health.query_modes.query_path }}
{% trans "Diff-capable maps" %} {{ health.query_modes.diff_capable }}
{% trans "Data-file-dependent maps" %} {{ health.query_modes.data_file_maps|length }} {% if health.query_modes.data_file_maps %} {% trans "Export Live Data File Check" %} {% endif %}
{% trans "Query Path Resolution" %}
{% with resolution=health.query_path_resolution %} {% if resolution.available %}
{% trans "Query path specs" %} {{ resolution.total_query_path_specs|placeholder }}
{% trans "Resolved specs" %} {{ resolution.resolved_spec_count|placeholder }}
{% else %}

{% trans "No query-path resolution telemetry is available for the latest ingestion." %}

{% endif %} {% endwith %}
{% trans "Query Drift Summary" %}
{% trans "Maps assessed" %} {{ health.query_drift_summary.total_maps|placeholder }}
{% trans "Warn / info / pass" %} {{ health.query_drift_summary.warn_count }}/{{ health.query_drift_summary.info_count }}/{{ health.query_drift_summary.pass_count }}
{% trans "Remediation actions" %} {% if health.query_drift_summary.remediation_actions %}
    {% for item in health.query_drift_summary.remediation_actions %}
  • {{ item.count }} - {{ item.message }}
  • {% endfor %}
{% else %} {% trans "No remediation actions emitted." %} {% endif %}
{% trans "Local Query Drift" %}
{% trans "Export Live Query Drift Check" %} {% if perms.forward_netbox.change_forwardnqemap %}
{% csrf_token %}
{% csrf_token %}
{% endif %} {% trans "Resolve existing queries read-only, or publish bundled source with NQE-library write permission." %}
{% for item in health.query_modes.local_drift %} {% empty %} {% endfor %}
{% trans "Map" %} {% trans "Mode" %} {% trans "Commit" %} {% trans "Status" %} {% trans "Message" %} {% trans "Remediation" %}
{{ item.name }} {{ item.mode }} {{ item.commit_message }} {% if item.severity == "pass" %} {{ item.status_label|default:item.status }} {% elif item.severity == "warn" %} {{ item.status_label|default:item.status }} {% else %} {{ item.status_label|default:item.status }} {% endif %} {{ item.message }} {{ item.remediation|default:"" }}
{% trans "No local query drift diagnostics available" %}
{% trans "Apply Engines" %}
{% trans "Selected engines" %} {{ health.apply_engines.selected }}
{% trans "Fallback reasons" %} {{ health.apply_engines.fallback_reasons }}
{% trans "Fetch Contracts" %}
{% trans "Fetch modes" %} {{ health.fetch_contracts.modes }}
{% trans "Shard-safe models" %} {{ health.fetch_contracts.shard_safe_count }}
{% trans "Model-fetch fallbacks" %} {{ health.fetch_contracts.model_fallback_count }}
{% trans "Collection Gap" %}
{% trans "Backfilled devices" %} {% if health.collection_gap.status == "danger" %} {{ health.collection_gap.backfilled_count }} {% elif health.collection_gap.status == "warn" %} {{ health.collection_gap.backfilled_count }} {% else %} {{ health.collection_gap.backfilled_count }} {% endif %}
{% trans "Status" %} {{ health.collection_gap.message }}
{% trans "Out of Scope" %}
{% trans "Out-of-scope devices" %} {% if health.out_of_scope.status == "warn" %} {{ health.out_of_scope.out_of_scope_count }} {% else %} {{ health.out_of_scope.out_of_scope_count }} {% endif %}
{% trans "Status" %} {{ health.out_of_scope.message }}
{% trans "Uncovered" %}
{% trans "Uncovered devices" %} {% if health.uncovered.status == "danger" %} {{ health.uncovered.uncovered_count }} {% elif health.uncovered.status == "warn" %} {{ health.uncovered.uncovered_count }} {% else %} {{ health.uncovered.uncovered_count }} {% endif %} {% if health.uncovered.trend_delta is not None %} {% blocktrans with delta=health.uncovered.trend_delta %}trend {{ delta }}{% endblocktrans %} {% endif %}
{% trans "Status" %} {{ health.uncovered.message }}
{% trans "Absence Quarantine" %}
{% trans "Thresholds" %} {% blocktrans with runs=health.quarantine_cadence.required_runs hours=health.quarantine_cadence.required_hours %}{{ runs }} runs and {{ hours }} hours{% endblocktrans %}
{% trans "Effective protection" %} {% if health.quarantine_cadence.effective_hours %} {% blocktrans with hours=health.quarantine_cadence.effective_hours binding=health.quarantine_cadence.binding %}about {{ hours }} hours ({{ binding }} threshold binds){% endblocktrans %} {% else %} {% trans "no recurrence interval" %} {% endif %}
{% trans "Status" %} {{ health.quarantine_cadence.message }}
{% trans "Density Learning" %}
{% trans "Tracked models" %} {{ health.density_learning.model_count|placeholder }}
{% trans "High confidence models" %} {{ health.density_learning.high_confidence_count|placeholder }}
{% trans "Medium confidence models" %} {{ health.density_learning.medium_confidence_count|placeholder }}
{% trans "Low confidence models" %} {{ health.density_learning.low_confidence_count|placeholder }}
{% for item in health.density_learning.models %} {% empty %} {% endfor %}
{% trans "Model" %} {% trans "Learned density" %} {% trans "Default density" %} {% trans "Samples" %} {% trans "Confidence" %}
{{ item.model }} {{ item.learned_density|placeholder }} {{ item.default_density|placeholder }} {{ item.sample_count|placeholder }} {{ item.confidence|placeholder }}
{% trans "No density learning samples are available yet" %}
{% trans "Latest State" %}
{% trans "Latest validation" %} {% if health.latest_validation %} {{ health.latest_validation.status }}{% if health.latest_validation.allowed %} ({% trans "allowed" %}){% endif %} {% else %} {{ ""|placeholder }} {% endif %}
{% trans "Latest ingestion" %} {% if health.latest_ingestion %} {{ health.latest_ingestion.name }}{% if health.latest_ingestion.baseline_ready %} ({% trans "baseline ready" %}{% if health.latest_ingestion.sync_mode %}, {% trans "sync mode" %}: {{ health.latest_ingestion.sync_mode }}{% endif %}){% elif health.latest_ingestion.sync_mode %} ({% trans "sync mode" %}: {{ health.latest_ingestion.sync_mode }}){% endif %} {% else %} {{ ""|placeholder }} {% endif %}
{% trans "Latest branch" %} {% if health.latest_ingestion.branch %} {{ health.latest_ingestion.branch }} ({{ health.latest_ingestion.branch_status|placeholder }}) {% else %} {{ ""|placeholder }} {% endif %}
{% trans "Ownership finalization" %} {% if health.ownership_finalization.complete %} {% trans "Complete" %} {% elif health.ownership_finalization.failed_domains %} {% trans "Failed" %}: {{ health.ownership_finalization.failed_domains|join:", " }} {% elif health.ownership_finalization.pending_domains %} {% trans "Pending" %}: {{ health.ownership_finalization.pending_domains|join:", " }} {% else %} {{ ""|placeholder }} {% endif %}
{% trans "Delete Wave" %}
{% trans "Phase" %} {{ health.delete_wave.phase|placeholder }}
{% trans "Summary" %} {{ health.delete_wave.message }}
{% trans "Deleted objects" %} {{ health.delete_wave.latest_ingestion.deleted_change_count|placeholder }}
{% trans "Dependency skip issues" %} {{ health.delete_wave.latest_ingestion.dependency_skip_issues.count|placeholder }}
{% trans "Current Branch & Jobs" %}
{% trans "Branch" %} {{ health.latest_ingestion.branch|placeholder }}
{% trans "Branch status" %} {{ health.latest_ingestion.branch_status|placeholder }}
{% trans "Stage job" %} {{ health.latest_ingestion.stage_job_status|placeholder }}
{% trans "Merge job" %} {{ health.latest_ingestion.merge_job_status|placeholder }}
{% trans "Applied / failed / skipped changes" %} {{ health.latest_ingestion.applied_change_count|placeholder }} / {{ health.latest_ingestion.failed_change_count|placeholder }} / {{ health.latest_ingestion.skipped_change_count|placeholder }}
{% trans "Ingestion issues" %} {{ health.latest_ingestion.issue_count|placeholder }}
{% if health.config_backup.enabled %}
{% trans "Config Backup" %}
{% if health.config_backup.shortfall %}

{{ health.config_backup.shortfall }}

{% endif %} {% if not health.config_backup.config_backup_jobs_found %} {% endif %} {% with result=health.config_backup.last_result %} {% if result %} {% endif %} {% endwith %}
{% trans "Last run" %} {{ health.config_backup.last_run_status|placeholder }}{% if health.config_backup.last_run_at %} · {{ health.config_backup.last_run_at }}{% endif %}{% if health.config_backup.last_skipped_reason %} · {{ health.config_backup.last_skipped_reason }}{% endif %}
{% trans "Note" %} {% trans "No config backup job exists for this sync, so there is no result to show. It has not run yet, or its job record was removed by NetBox's job retention; use Back up configs on the sync page to run one and record its result." %}
{% trans "Managed devices" %} {{ result.scoped_devices|placeholder }}{% if health.config_backup.in_scope_devices_now is not None %} ({% blocktrans with count=health.config_backup.in_scope_devices_now %}{{ count }} now{% endblocktrans %}){% endif %}
{% trans "Managed devices with no config from Forward" %} {{ result.scoped_without_config|placeholder }}
{% trans "Rows fetched" %} {{ result.rows|placeholder }} ({{ result.pages|placeholder }} {% trans "pages" %})
{% trans "Written / unchanged / unmapped" %} {{ result.written|placeholder }} / {{ result.unchanged|placeholder }} / {{ result.unmapped|placeholder }}
{% trans "Unmanaged written / unchanged" %} {{ result.unmanaged_written|placeholder }} / {{ result.unmanaged_unchanged|placeholder }}
{% trans "Files in the backup folder" %} {{ result.files_in_folder|placeholder }}
{% trans "Snapshot" %} {{ result.snapshot_id|placeholder }}
{% trans "Commit / pushed" %} {{ result.commit|placeholder }} / {% if result.pushed %}{% trans "yes" %}{% else %}{% trans "no" %}{% endif %}
{% trans "Duration (seconds)" %} {{ result.duration_seconds|placeholder }}
{% trans "Validity device_config_path" %} {% if health.config_backup.validity_installed %} {% if health.config_backup.device_config_path_matches_prefix %} {% trans "Matches the backup folder." %} {% elif health.config_backup.device_config_path_set %} {% trans "Does not match the backup folder." %} {% else %} {% trans "Not set." %} {% endif %} {% trans "Set it to" %} {{ health.config_backup.expected_device_config_path }} {% else %} {% trans "Validity is not installed." %} {% endif %}
{% endif %}
{% trans "NetBox vs Forward Row Counts" %}

{% trans "Rows Forward returned in the latest validation run beside the rows NetBox holds for each enabled model. NetBox counts the whole table, including rows this sync does not manage, so a NetBox count far below Forward's is the signal that earlier runs never loaded the model." %}

{% for entry in health.row_counts.models %} {% empty %} {% endfor %}
{% trans "Model" %} {% trans "Forward" %} {% trans "NetBox" %} {% trans "Before latest run" %} {% trans "Created since" %} {% trans "Duplicate groups" %} {% trans "Note" %}
{{ entry.model }} {{ entry.forward_rows|placeholder }} {{ entry.netbox_rows|placeholder }} {{ entry.rows_before_latest_run|placeholder }} {{ entry.rows_created_since|placeholder }} {{ entry.duplicate_groups|placeholder }} {{ entry.note }}
{% trans "No enabled models." %}
{% trans "Recent Ingestions" %}

{% trans "An Auto merge runs inside the sync job, so its merge shows no separate merge job; the merge time and counts below are the record of it." %}

{% for item in health.recent_ingestions.ingestions %} {% empty %} {% endfor %}
{% trans "Ingestion" %} {% trans "Mode" %} {% trans "Job" %} {% trans "Merge" %} {% trans "Changes merged" %}
{{ item.ingestion }} {{ item.sync_mode|placeholder }}{% if item.baseline_ready %} ({% trans "baseline" %}){% endif %} {{ item.job_status|placeholder }}
{{ item.job_started|placeholder }} → {{ item.job_completed|placeholder }}
{{ item.merge.mode }}
{{ item.merge.merge_applied_at|placeholder }}
{{ item.merged_changes_by_model_action.total|placeholder }}{% if item.merged_changes_by_model_action.note %}
{{ item.merged_changes_by_model_action.note }}{% endif %}
{% trans "No ingestions yet." %}
{% include 'extras/inc/configcontext_data.html' with title="Health Details" data=health format="json" copyid="forward-sync-health-details" %}
{% plugin_right_page object %}
{% endblock content %}