NetAuto Academy

Netmiko Fundamentals

Multiple Devices, Failures, and Timeouts

Beginner14 min read

What you'll learn

  • How to combine connection, command execution, and parsing into one function
  • How to translate Netmiko's real exceptions into the same exception the Phase 2.6 loop already expects
  • Why a timeout and an authentication failure are different problems, even though both mean 'no state'
  • How to loop connect_and_check() over an entire inventory without one bad device stopping the rest
  • That the surrounding loop from Phase 2.6 genuinely does not need to change
🎓 Teach This Lesson

Listen to a guided explanation of this lesson.

Spoken narration isn't supported in this browser.

Assembling the real connection/check function

Every piece is already built: connecting (Lesson 2), running commands and parsing them (Lesson 3), and handling connection failures (Lesson 2). This lesson combines them into one function — the real counterpart to simulate_connection():

connect_and_check.py
from netmiko import ConnectHandler, NetmikoTimeoutException, NetmikoAuthenticationException


def connect_and_check(device, username, password):
  """
  Connects to a real device over SSH and returns its NTP and VLAN
  compliance state — the real implementation behind the same seam
  simulate_connection() filled with mock data in the last module.
  """
  try:
      connection = ConnectHandler(
          device_type=device["platform"],
          host=device["ip"],
          username=username,
          password=password,
          conn_timeout=10,
      )
  except NetmikoTimeoutException:
      raise ConnectionError(f"{device['hostname']} did not respond (timeout)")
  except NetmikoAuthenticationException:
      raise ConnectionError(f"{device['hostname']} rejected the credentials (authentication failure)")

  ntp_output = connection.send_command("show ntp status")
  vlan_output = connection.send_command("show vlan brief")
  connection.disconnect()

  return {
      "reachable": True,
      "ntp_synced": is_ntp_synced(ntp_output),
      "vlan_compliant": is_vlan_present(vlan_output, 20),
  }

device['platform'] and device['ip'] come straight from the Phase 2.6 inventory unchanged. username and password are new parameters — never read from the device dictionary, matching Lesson 1's warning.

Same exception, new reasons — on purpose

Notice both except blocks raise ConnectionError — the exact exception type Phase 2.6's calling loop already catches. Netmiko's own exceptions are caught inside this function and translated at the boundary, so everything outside connect_and_check() keeps working against the same contract it always has. The real reason (timeout vs. authentication failure) still reaches the printed message — it's just not a new exception type the rest of the project needs to know about.

Quick checkConcept check
Why does connect_and_check() catch NetmikoTimeoutException and NetmikoAuthenticationException, and then raise ConnectionError in both cases, instead of letting the original Netmiko exceptions propagate?
Quick checkScenario
A timeout and an authentication failure both end up reported as ConnectionError from connect_and_check(). Does that mean they're the same problem?

Looping over the whole inventory

This is where the payoff shows up — the exact loop shape from "Your First Network Automation," calling the real function instead of the mock one:

check_all_devices.py
import getpass

username = input("Username: ")
password = getpass.getpass("Password: ")

results = []

for device in valid_devices:
  print(f"Checking {device['hostname']}...")

  try:
      state = connect_and_check(device, username, password)
  except ConnectionError as e:
      print(f"{device['hostname']}: {e}")
      results.append({
          "hostname": device["hostname"],
          "ip": device["ip"],
          "status": "unreachable",
      })
      continue

  status = check_compliance(state)
  print(f"{device['hostname']}: {status}")
  results.append({
      "hostname": device["hostname"],
      "ip": device["ip"],
      "status": status,
  })

Compare this line by line against Lesson 5 of 'Your First Network Automation' — it's the same loop. Only the function being called, and the two new credential variables feeding it, are different.

Quick checkMyth check
Does the main processing loop shown above need to be rewritten to work with real Netmiko connections, compared to the Phase 2.6 version that called simulate_connection()?
Quick checkIdentify the correct code
Which line correctly ensures that one device's connection failure doesn't stop the remaining devices in valid_devices from being checked?
Quick checkScenario
Running this against a 3-device inventory, SW1 connects and checks fine, SW2's credentials are rejected, SW3 times out. How many entries does results contain at the end?

Key takeaways

  • connect_and_check() combines connecting, running commands, and parsing into one function with the same role simulate_connection() played.
  • Netmiko's specific exceptions are caught inside that function and translated into the same ConnectionError the rest of the project already expects — a deliberate, stable boundary.
  • A timeout and an authentication failure are different real-world problems, even though both are reported through the same exception type — the message still distinguishes them.
  • The main processing loop from 'Your First Network Automation' needed zero structural changes — proof that the architectural seam held.
  • Every device in an inventory gets exactly one result, whatever happens — the same honest, non-stopping failure handling this curriculum has built since 'Validation, Safety & Failure Handling.'