netops.inventory — Device Discovery¶
Subnet scanning and automatic device discovery.
netops.inventory.scan¶
Scan subnets for network devices using ping sweep and SNMP fingerprinting.
Produces ScanResult objects that can be merged into an existing inventory
or exported as a new YAML/JSON inventory file.
CLI usage:
python -m netops.inventory.scan --subnet 10.0.0.0/24
python -m netops.inventory.scan --subnet 10.0.0.0/24 --community public
python -m netops.inventory.scan --subnet 10.0.0.0/24 --output inventory.yaml
python -m netops.inventory.scan --subnet 10.0.0.0/24 --json
python -m netops.inventory.scan --subnet 10.0.0.0/24 --deep-enrich
scan ¶
Subnet scanner — discover devices via SNMP/CDP/LLDP/ping sweep.
Usage: python -m netops.inventory.scan --subnet 10.0.0.0/24 --community public python -m netops.inventory.scan --subnet 10.0.0.0/24 --output fragment.json python -m netops.inventory.scan --subnet 10.0.0.0/24 --merge existing.yaml python -m netops.inventory.scan --csv hosts.csv --user admin python -m netops.inventory.scan --hosts-file ips.txt --user admin
Classes¶
ScanResult
dataclass
¶
ScanResult(host: str, reachable: bool, hostname: str | None = None, sys_descr: str | None = None, sys_obj_id: str | None = None, vendor: str | None = None, location: str | None = None, cdp_neighbors: list[dict] = list(), lldp_neighbors: list[dict] = list(), error: str | None = None, version: str | None = None, model: str | None = None, serial: str | None = None, uptime: str | None = None, image: str | None = None, hardware_revision: str | None = None, total_memory: str | None = None, free_memory: str | None = None, reload_reason: str | None = None, mac_address: str | None = None, config_register: str | None = None, cpu_type: str | None = None, flash_size: str | None = None, domain_name: str | None = None, interface_count: str | None = None)
Functions:¶
ping_host ¶
Return True if host responds to ICMP ping.
ping_sweep ¶
Ping sweep a subnet and return a sorted list of reachable IP address strings.
Args:
subnet: CIDR notation subnet (e.g. "10.0.0.0/24").
max_workers: Thread pool size for concurrent pings.
timeout: Per-host ping timeout in seconds.
identify_vendor ¶
Map sysDescr / sysObjectID to a Netmiko-compatible vendor string.
Returns one of: cisco_ios, cisco_xe, cisco_xr, cisco_nxos,
nokia_sros, nokia_srl, juniper_junos, arista_eos,
brocade_fastiron, brocade_nos, or "unknown".
scan_subnet_async
async
¶
scan_subnet_async(subnet: str, community: str = 'public', snmp_port: int = 161, snmp_timeout: int = 2, ping_workers: int = 50, ping_timeout: int = 1, snmp_concurrency: int = 10, skip_ping: bool = False, skip_snmp: bool = False) -> list[ScanResult]
Async implementation of the full subnet scan pipeline.
scan_subnet ¶
scan_subnet(subnet: str, community: str = 'public', snmp_port: int = 161, snmp_timeout: int = 2, ping_workers: int = 50, ping_timeout: int = 1, snmp_concurrency: int = 10, skip_ping: bool = False, skip_snmp: bool = False) -> list[ScanResult]
Full subnet scan: ping sweep → SNMP identification → CDP/LLDP topology.
Args:
subnet: CIDR notation subnet (e.g. "10.0.0.0/24").
community: SNMPv2c community string.
snmp_port: SNMP UDP port (default 161).
snmp_timeout: Per-host SNMP timeout in seconds.
ping_workers: Ping sweep thread-pool size.
ping_timeout: Per-host ping timeout in seconds.
snmp_concurrency: Max simultaneous SNMP sessions.
skip_ping: Skip ping sweep and probe all addresses in the subnet.
skip_snmp: Skip SNMP — perform a ping-sweep only.
Returns:
list
Sorted list of :class:ScanResult objects (one per reachable host).
Requires:
pysnmp >= 7.0. Install with pip install 'netops-toolkit[snmp]'.
scan_subnet_through_active_bastion ¶
scan_subnet_through_active_bastion(subnet: str, ssh_port: int = 22, max_workers: int = 50, timeout: int = 3) -> list[ScanResult]
Discover SSH-reachable hosts through the selected workstation bastion.
SSH forwarding transports TCP, not local ICMP or UDP. When a bastion is active, discovery therefore probes each address's SSH port through the shared SOCKS service instead of incorrectly running ping/SNMP on the workstation's local network.
results_to_inventory_fragment ¶
Convert scan results to an inventory fragment ({"devices": {...}} dict).
The fragment is compatible with :class:netops.core.Inventory and can be
written directly as a JSON file or merged into an existing inventory.
merge_inventory ¶
Merge a scan fragment into an existing inventory file.
New devices are added. Existing entries are updated only where the
current value is None, "unknown", or "" — manually-set
values are never overwritten.
Args:
existing_path: Path to an existing YAML or JSON inventory file.
If the file does not exist, an empty inventory is used as the base.
fragment: Inventory fragment produced by :func:results_to_inventory_fragment.
Returns:
dict Merged inventory dict.
deep_enrich ¶
deep_enrich(fragment: dict, username: str, password: str, concurrency: int = 5, timeout: int = 15, port: int | None = None, community_registry: CommunityRegistry | None = None) -> dict
Enrich an inventory fragment with SSH-gathered details.
Connects to each device in the fragment, auto-detects vendor if unknown, and updates vendor, version, model, serial in-place.
Args:
fragment: Inventory fragment ({"devices": {...}}).
username: SSH username for all devices.
password: SSH password for all devices.
concurrency: Max parallel SSH sessions.
timeout: Per-device connection timeout in seconds.
port: Optional SSH port override.
community_registry: Optional privileged registry for discovered SNMP
communities. Values are never copied into the inventory fragment.
Returns:
dict The enriched fragment (modified in-place and returned).