NetAuto Academy

Beginner Lab

Netmiko-Style Fleet Health Check

Beginner20 min

Objective

Parse a device's reported hostname out of sample show version text and compare it against your inventory's expectation, producing a three-state health report across a small fleet.

Builds on Netmiko Fundamentals.

Prerequisites

  • Comfortable with what conn.send_command() returns (Running Show Commands with Netmiko)
  • Comfortable with dictionaries and loops
Local/offline only. All command output below is fixed sample text, not a real connection -- no device, credential, or connection of any kind.

Scenario

The problem

Your inventory says SW1, SW2, SW3, and SW4 exist. But inventories drift from reality -- a device gets renamed during a maintenance window and nobody updates the source of truth, or a device stops responding entirely. This lab checks each device's own reported identity against what your inventory expects, exactly the kind of check "Your First Network Automation" ran for VLANs, applied here to hostname identity instead.

Starter data

starter.py
INVENTORY = ["SW1", "SW2", "SW3", "SW4"]

# Stands in for what conn.send_command("show version") would return per
# device over a real Netmiko connection -- fixed sample text, not a live device.
SAMPLE_SHOW_VERSION = {
  "SW1": "Cisco IOS Software, C2960 Software\nSW1 uptime is 10 days, 4 hours, 12 minutes",
  "SW2": "Cisco IOS Software, C2960 Software\nSW2-OLD uptime is 3 days, 1 hour, 5 minutes",
  "SW3": "Cisco IOS Software, C2960 Software\nSW3 uptime is 45 days, 0 hours, 30 minutes",
}

Fixed sample data written for this lab. Notice SAMPLE_SHOW_VERSION only has 3 entries -- SW4 is in the inventory but never responded, exactly as a real unreachable device would look.

Task

Write parse_hostname_from_version(output) that finds the line containing "uptime is" and returns its first word (the hostname the device itself reports).

Then write health_check(inventory, command_outputs) that, for every hostname in inventory:

  • If there's no entry in command_outputs for it, record {"status": "unreachable"}.
  • If the parsed hostname matches the inventory hostname, record {"status": "ok"}.
  • Otherwise, record {"status": "hostname_mismatch", "expected": ..., "reported": ...}.

Return one dict keyed by inventory hostname.

Hints

Expected output

expected output
SW1: {'status': 'ok'}
SW2: {'status': 'hostname_mismatch', 'expected': 'SW2', 'reported': 'SW2-OLD'}
SW3: {'status': 'ok'}
SW4: {'status': 'unreachable'}

Real, verified output -- all three status branches (ok, mismatch, unreachable) genuinely produced by this exact starter data.

Validation checklist

Self-check only -- nothing here is submitted or graded. Compare against your own output manually.

Solution

Solution

Try the task yourself first -- the full solution and explanation stay hidden until you click above.

Key takeaways

  • A device's own reported identity can drift from what your inventory expects -- worth checking directly, not assuming.
  • Three real outcomes (ok, mismatch, unreachable) need three distinct report states, not a single pass/fail flag.
  • Checking for missing data before parsing it prevents a crash on the exact case (a non-responding device) this check exists to catch.
  • All command output here is fixed sample text -- no device or connection was used or required.

Related lessons

Done with this lesson?