Safe Python Netmiko patterns for read-only collection, bounded batch SSH, TextFSM parsing, guarded config changes, timeouts, and network automation error handli
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-netmiko-ssh-automation-ce089ab90fb4 ,按照其中的说明把「netmiko-ssh-automation」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
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.
show command output across routers, switches, or firewalls.send_command() collection.getpass; never hardcode credentials.send_config_set().save_config() until the change has been verified and approved.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.
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.
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.
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.
conn_timeout, auth_timeout, and command read_timeout set?save_config() separate from the initial push and tied to verification?cisco-ios-patternsnetwork-config-validationnetwork-interface-health