{% extends "base.html" %} {% block title %}Definitions — Netcanon{% endblock %} {# Definitions browser — four sections: 1. Backup-side device definitions (family-base YAMLs). 2. Version / model overlays (loaded but filtered out of load_all). 3. Migration target profiles (per-model hardware; 50+ entries previously only accessible via the Tier-3 rename modal). 4. Vendors + codec capabilities (the 8 migration vendors with shipped codecs, direction, certainty tier). Every section carries a `section-` testid on the container so e2e tests can jump to a section without enumerating every inner element. Collapsible blocks use the native
/ elements — zero JS, browser-built-in keyboard + screen- reader behaviour. Custom colours driven by theme tokens (see ARCHITECTURE.md "Theming (dark mode)"). #} {% block content %}

Definitions Browser

What Netcanon knows about: backup-side device definitions ({{ definitions | length }} family-base + {{ overlays | length }} overlay), migration target profiles ({{ target_profile_count }} hardware models across {{ profiles_by_vendor | length }} vendor{{ 's' if profiles_by_vendor | length != 1 else '' }}), and {{ vendor_rows | length }} vendor codec{{ 's' if vendor_rows | length != 1 else '' }} with capability matrices.

{# ═════════════════ 1. Backup-side device definitions ═════════════════ #}

Backup-side device definitions

{{ definitions | length }}
{% if definitions %} {% for def in definitions %} {% endfor %}
Type KeyVendorOS CollectionFile ExtPriorityNotes
{{ def.type_key }} {{ def.vendor }} {{ def.os }} {% if def.collector.strategy == 'netmiko' %} SSH (Netmiko) {% if def.collector.netmiko_device_type %}
{{ def.collector.netmiko_device_type }} {% endif %} {% elif def.collector.strategy == 'paramiko_shell' %} SSH (Shell) {% else %} {{ def.collector.strategy }} {% endif %}
.{{ def.file_extension }} {{ def.priority }} {{ def.notes | truncate(120) }}
{% else %}

No definitions loaded. Add YAML files to the definitions/ directory and click Reload from disk.

{% endif %}
{# ═════════════════ 2. Version / model overlays ═════════════════ #}

Version / model overlays

{{ overlays | length if overlays else 0 }}

Overlays are YAML variants that pin a specific OS version or model (e.g. ``Cisco 17.12``). They're stored in the loader's variant registry and resolved by {# Link is informational; the actual resolve() call lives in netcanon/definitions/loader.py. Don't link-rot. #} DefinitionLoader.resolve() during backup — longest match wins. The main definitions table above shows only the family bases; this list explains the "loaded N but showed N-M" split on the startup log.

{% if overlays %} {% for ov in overlays %} {% endfor %}
Type KeyOS VersionModel PriorityFile
{{ ov.type_key }} {% if ov.os_version %}{{ ov.os_version }} {% else %}{% endif %} {% if ov.model %}{{ ov.model }} {% else %}{% endif %} {{ ov.priority }} {{ ov.source_file | default('', true) }}
{% else %}

No overlays loaded. All backups will use the family-base definition for their device type. Drop a YAML file under definitions/ with an os_version or model field to pin behaviour for a specific firmware revision (e.g. cisco_ios_17.12.yaml).

{% endif %}
{# ═════════════════ 3. Migration target profiles ═════════════════ #}

Migration target profiles

{{ target_profile_count }}

Hardware-aware profiles from definitions/target_profiles/: per-model port inventories, module variants, stacking capabilities, VLAN + user limits. The Tier-3 rename modal uses these to validate port assignments; they're shown here for discovery + browsing.

{% if target_profile_count %}
{% for vendor_key, profiles in profiles_by_vendor %}
{{ vendor_key }} — {{ profiles | length }} profile{{ 's' if profiles | length != 1 else '' }}
{% for p in profiles %}
{{ p.display_name or (p.vendor ~ ' ' ~ p.model) }} {{ p.model }} · {{ p.device_class.value if p.device_class.value is defined else p.device_class }} {% if p.has_modules %} · {{ p.modules | length }} module variant{{ 's' if p.modules | length != 1 else '' }} {% endif %} · {{ p.port_count }} base port{{ 's' if p.port_count != 1 else '' }}
Vendor
{{ p.vendor }}
Model
{{ p.model }}
{% if p.stacking %}
Stacking
{{ p.stacking }}
{% endif %}
Device class
{{ p.device_class.value if p.device_class.value is defined else p.device_class }}
{% if p.lags %}
LAGs
max {{ p.lags.max }} {% if p.lags.prefix %}· prefix {{ p.lags.prefix }}{% endif %}
{% endif %} {% if p.max_vlans is not none %}
Max VLANs
{{ p.max_vlans }} {% if p.max_vlans_source %} ({{ p.max_vlans_source }}) {% endif %}
{% endif %} {% if p.max_local_users is not none %}
Max local users
{{ p.max_local_users }}
{% endif %}
{% if p.ports %}
Base ports ({{ p.ports | length }})
{% for port in p.ports %} {{ port.id }} {% endfor %}
{% endif %} {% if p.has_modules %}
Module variants ({{ p.modules | length }})
{% for sku, mod in p.modules.items() %}
{{ sku }} {% if mod.description %} {{ mod.description }} {% endif %}
{% if mod.ports %}
{% for port in mod.ports %} {{ port.id }} {% endfor %}
{% endif %}
{% endfor %} {% endif %}
{% endfor %}
{% endfor %} {% else %}

No target profiles loaded. The Tier-3 rename modal will fall back to free-form port names.

{% endif %}
{# ═════════════════ 4. Vendors + codec capabilities ═════════════════ #}

Migration vendors + codec capabilities

{{ vendor_rows | length }}

Each vendor ships with one or more codecs that parse / render its configuration format. Direction: parse-only vs bidirectional. Certainty tier: certified (≥3 real captures from ≥2 OS versions, all round-trip stable) · best_effort (≥1 real capture round-trips clean) · experimental (synthetic fixtures only).

{% for row in vendor_rows %}
{{ row.info.display_name }} {{ row.info.id }} {% if row.info.device_classes %} · {% for dc in row.info.device_classes %} {{ dc.value if dc.value is defined else dc }}{% if not loop.last %},{% endif %} {% endfor %} {% endif %} · {{ row.codecs | length }} codec{{ 's' if row.codecs | length != 1 else '' }}
{% if row.info.notes %}

{{ row.info.notes }}

{% endif %} {% if row.codecs %} {% for c in row.codecs %} {% endfor %}
CodecDirectionCertainty Input formatPaths
{{ c.name }} {{ c.direction }} {{ c.certainty }} {{ c.input_format }} {# Each chip is a button: clickable when count > 0, disabled (greyed) when 0. Click toggles a detail row inserted below this codec's row showing the bucket's actual xpaths + reasons. See the ``codec-caps-chip-*`` testids for the click handlers. #} · ·
{% else %}

No codecs registered for this vendor.

{% endif %}
{% endfor %}
{% endblock %} {% block scripts %} {% endblock %}