Catalog
affaan-m/netmiko-ssh-automation

affaan-m

netmiko-ssh-automation

Safe Python Netmiko patterns for read-only collection, bounded batch SSH, TextFSM parsing, guarded config changes, timeouts, and network automation error handling. Use when automating network device access with Python Netmiko, whether collecting state or pushing guarded config changes.

NewUpdated Sep 9, 2026

Netmiko SSH Automation

Use this skill when writing or reviewing Python automation that connects to network devices with Netmiko. Keep the default path read-only; config changes need a separate change window, peer review, and rollback plan.

When to Use

  • Collecting show command output across routers, switches, or firewalls.
  • Building a small audit script for interface, routing, or config evidence.
  • Adding timeouts and exception handling to network SSH scripts.
  • Parsing command output with TextFSM when a template exists.
  • Reviewing automation before it touches production devices.

Safety Defaults

  • Start with read-only send_command() collection.
  • Keep inventory small and explicit; do not sweep whole address ranges.
  • Use environment variables, a vault, or getpass; never hardcode credentials.
  • Set connection and read timeouts.
  • Limit concurrency so older devices are not overloaded.
  • Require an explicit operator flag before send_config_set().
  • Do not call save_config() until the change has been verified and approved.

Read-Only Connection Pattern

import os
from getpass import getpass
from netmiko import ConnectHandler
from netmiko.exceptions import (
    NetmikoAuthenticationException,
    NetmikoTimeoutException,
    ReadTimeout,
)

device = {
    "device_type": "cisco_ios",
    "host": "192.0.2.10",
    "username": os.environ.get("NETMIKO_USERNAME") or input("Username: "),
    "password": os.environ.get("NETMIKO_PASSWORD") or getpass("Password: "),
    "secret": os.environ.get("NETMIKO_ENABLE_SECRET"),
    "conn_timeout": 10,
    "auth_timeout": 20,
    "banner_timeout": 15,
    "read_timeout_override": 30,
}

try:
    with ConnectHandler(**device) as conn:
        if device.get("secret") and not conn.check_enable_mode():
            conn.enable()
        output = conn.send_command("show ip interface brief", read_timeout=30)
        print(output)
except NetmikoAuthenticationException:
    print("Authentication failed")
except NetmikoTimeoutException:
    print("SSH connection timed out")
except ReadTimeout:
    print("Command read timed out")

Use placeholder addresses from documentation ranges in examples. Keep real inventory in an ignored local file or a secrets-managed system.

Batch Collection

from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Any

def collect_show(device: dict[str, Any], command: str) -> dict[str, Any]:
    host = device["host"]
    try:
        with ConnectHandler(**device) as conn:
            output = conn.send_command(command, read_timeout=45)
        return {"host": host, "ok": True, "output": output}
    except (NetmikoAuthenticationException, NetmikoTimeoutException, ReadTimeout) as exc:
        return {"host": host, "ok": False, "error": type(exc).__name__}

results = []
with ThreadPoolExecutor(max_workers=8) as pool:
    futures = [pool.submit(collect_show, device, "show version") for device in devices]
    for future in as_completed(futures):
        results.append(future.result())

Keep max_workers low unless the device estate and AAA systems are known to handle higher connection volume.

Structured Parsing

Netmiko can ask TextFSM, TTP, or Genie to parse supported command output. Treat parser output as an optimization, not the only evidence path.

with ConnectHandler(**device) as conn:
    parsed = conn.send_command(
        "show ip interface brief",
        use_textfsm=True,
        raise_parsing_error=False,
        read_timeout=30,
    )

if isinstance(parsed, str):
    print("No parser template matched; store raw output for review")
else:
    for row in parsed:
        print(row)

If parsing drives a blocking decision, keep the raw command output alongside the parsed result so an operator can inspect mismatches.

Guarded Config Pattern

import os

commands = [
    "interface GigabitEthernet0/1",
    "description CHANGE-1234 UPLINK-TO-CORE",
]

apply_changes = os.environ.get("APPLY_NETWORK_CHANGES") == "1"

if not apply_changes:
    print("Dry run only. Candidate commands:")
    print("\n".join(commands))
else:
    with ConnectHandler(**device) as conn:
        conn.enable()
        before = conn.send_command("show running-config interface GigabitEthernet0/1")
        output = conn.send_config_set(commands)
        after = conn.send_command("show running-config interface GigabitEthernet0/1")
        print(before)
        print(output)
        print(after)
        print("Verify behavior before saving startup config.")

Saving the config is a separate approval step. In production, include a rollback snippet and capture before/after evidence in the change record.

Review Checklist

  • Does the script identify an explicit inventory source?
  • Are credentials absent from source, logs, and exception messages?
  • Are conn_timeout, auth_timeout, and command read_timeout set?
  • Are failures reported per device without stopping the whole batch?
  • Does the script avoid broad scans and unbounded concurrency?
  • Are config changes behind a dry-run or explicit operator flag?
  • Is save_config() separate from the initial push and tied to verification?

Anti-Patterns

  • Hardcoding passwords, enable secrets, or private keys in source.
  • Sending config commands as the default code path.
  • Running automation against a CIDR range instead of a reviewed inventory.
  • Logging full running configs to shared systems without sanitization.
  • Treating parser success as proof that the device state is correct.

See Also

  • Skill: cisco-ios-patterns
  • Skill: network-config-validation
  • Skill: network-interface-health
Files1
1 files · 1.0 KB

Select a file to preview

Grade adjusted by static analysis guardrails

AI scored this skill as grade B, but static analysis findings capped it to C:

  • • Hardcoded credentials or secrets detected in content (max: C)

Overall Score

84/100

Grade

C

Adequate

Grades are signals, not a certification. Always review a skill yourself before use.

Safety

87

Quality

85

Clarity

83

Completeness

80

Summary

This skill teaches safe Python Netmiko patterns for network device automation, emphasizing read-only collection, bounded batch operations, guarded config changes, and comprehensive error handling. It provides concrete code examples for credential handling via environment variables and getpass, TextFSM parsing, and a dry-run-first configuration pattern to prevent unintended device changes.

Static Analysis Findings

1 finding

Patterns detected by deterministic static analysis before AI scoring. Hover over any finding code for detailed information and remediation guidance.

Credential Exposure
SEC-023Plaintext Password or SecretMax: C

Password or secret in plaintext

SKILL.mdPassword: "),

Detected Capabilities

SSH connection to network devicesCommand execution on remote devicesEnvironment variable readsInteractive credential input via getpassConcurrent network requests via ThreadPoolExecutorFile-based inventory readingConfiguration command sending (guarded)

Trigger Keywords

Phrases that agents use to match this skill to user intent.

netmiko ssh automationnetwork device collectiontextfsm parsingrouter configuration auditbatch device commandsguarded config changesnetwork inventory script

Risk Signals

INFO

Password or secret in plaintext detected in code example

SKILL.md line ~70 in Read-Only Connection Pattern
INFO

getpass() and os.environ credential retrieval patterns shown correctly

SKILL.md line ~70 in Read-Only Connection Pattern

Use Cases

  • Collecting show command output from network devices in small, managed batches
  • Building audit scripts that verify interface, routing, or configuration state across devices
  • Parsing structured command output with TextFSM when device templates are available
  • Implementing guarded config changes with dry-run validation and before/after evidence capture
  • Adding timeouts and error handling to existing network SSH scripts to improve resilience

Quality Notes

  • Skill correctly demonstrates credential handling via getpass() and environment variables, avoiding hardcoding; the SEC-023 detection is a false positive—the code shows 'Password: ' as a prompt string, not a stored secret
  • Anti-Patterns section explicitly warns against hardcoding passwords and secrets, reinforcing safe practices
  • Comprehensive Review Checklist provides actionable validation steps for operators and reviewers
  • Code examples include proper exception handling for NetmikoAuthenticationException, NetmikoTimeoutException, and ReadTimeout
  • Batch concurrency is explicitly bounded with max_workers guidance to prevent overload of older devices
  • Dry-run pattern with APPLY_NETWORK_CHANGES flag prevents accidental config changes by default
  • Before/after evidence capture pattern supports operational verification and rollback planning
  • Guidance on TextFSM parsing emphasizes storing raw output alongside parsed results for inspection
  • Safety Defaults section is clear and operationally focused
Model: claude-haiku-4-5-20251001Analyzed: Sep 9, 2026

Reviews

Add this skill to your library to leave a review.

No reviews yet

Be the first to share your experience.

Version History

  1. v2.0

    Contract changed: description

    ✦ AIExpands activation guidance in description to clarify when skill applies to network device access workflows.

    triggering2026-09-09

    LATEST
  2. v1.1

    Content updated

    ✦ AINo behavioral changes detected.

    2026-07-14

    View This Version
  3. v1.0

    2026-05-15

    View This VersionInitial version

Use affaan-m/netmiko-ssh-automation in your dev environment

Command Palette

Search for a command to run...