我使用以下脚本登录到各种cisco设备并对它们进行配置:
from netmiko import ConnectHandler
import time
import json
import yaml
import sys
with open("devices.yml") as d:
all_devices = yaml.safe_load(d)
with open("snmp_configs.txt") as c:
lines = c.read().splitlines()
with open("exception_log.txt", "w") as log:
for devices in all_devices:
try:
net_connect = ConnectHandler(**devices)
output = net_connect.send_config_set(lines)
print("Configuring Device")
time.sleep(5)
#except BaseException as ex:
#ex_value = sys.exc_info()
#print(ex_value)
except:
print ("An Exception Occurred, Skipping")
traceback.print_exc(file=log)
continue该脚本将yaml文件用于如下所示的设备:
-device_type: cisco_ios
ip: 192.168.122.71
username: admin
password: cisco
-device_type: cisco_ios
ip: 192.168.122.81
username: admin
password: cisco我的问题是这个。如果我有几十个甚至几百个设备使用相同的用户名和密码,是否有办法不需要在文件中一次又一次地重复用户名、密码和设备类型信息?我想知道是否有一种方法只需在文件中输入用户名和密码一次,那么文件的其余部分仅仅是设备的IP地址?
我希望这是有意义的。
谢谢。
发布于 2022-08-03 14:50:59
您可以使用动态库存,如我在下面共享的示例中所示。
myhelper.py非常小心地解析inventory.yml文件。确保此脚本与repo中的任何脚本位于相同的位置。
inventory.yml
all:
vars:
username: admin
password: admin
sites:
- name: am3
hosts:
- hostname: am3-srx-fw-1
host: 10.1.1.1
device_type_netmiko: juniper_junos
device_type: srx
device_role: edge
- hostname: ld5-srx-fw-1
host: 10.2.2.2
device_type_netmiko: juniper_junos
device_type: srx
device_role: edgemyhelper.py
import yaml
import os
#SITES = {"sjc": 1, "bru": 2}
#DEVICE_TYPES = {"csr1000v": 1, "iosv-l2": 2}
#DEVICE_ROLES = {"access": 1, "edge": 2, "core": 3}
#site_name="opc"
path="inventory.yml"
def read_yaml(path="inventory.yml"):
with open(path) as f:
yaml_content = yaml.load(f.read())
return yaml_content
def form_connection_params_from_yaml(parsed_yaml):
global_params = parsed_yaml["all"]["vars"]
found = False
for site_dict in parsed_yaml["all"]["sites"]:
for host in site_dict["hosts"]:
#print(host)
host_dict = {}
if "device_type_netmiko" in host:
host["device_type"] = host.pop("device_type_netmiko")
host_dict.update(global_params)
host_dict.update(host)
host_dict.pop("device_role")
host_dict.pop("hostname")
found = True
yield host_dict
#if site_name is not None and not found:
#raise KeyError(
# "Site {} is not specified in inventory YAML file".format(site_name)
#)
#def main():
#parsed_yaml = read_yaml()
#connection_params = form_connection_params_from_yaml(parsed_yaml, site_name="opc")
#print(connection_params)network.sanity.py
import netmiko
from myhelper import read_yaml, form_connection_params_from_yaml
import logging
logging.basicConfig(filename='dynamic.log', level=logging.DEBUG)
logger = logging.getLogger("netmiko")
path = raw_input("Enter the name of commandi file:")
COMMANDS_LIST = open(path).readlines()
def collect_outputs(devices, commands):
"""
Collects commands from the dictionary of devices
Args:
devices (dict): dictionary, where key is the hostname, value is
netmiko connection dictionary
commands (list): list of commands to be executed on every device
Returns:
dict: key is the hostname, value is string with all outputs
"""
for device in devices:
hostname = device.pop("hostname")
connection = netmiko.ConnectHandler(**device)
print(hostname)
with open(hostname , "a") as f:
for command in commands:
print(command)
command_result = connection.send_command(command, delay_factor=10)
# with open(hostname , "a") as f:
f.write(command)
f.write(command_result)
connection.disconnect
yield command_result
def getdevicename(parsed_yaml):
parsed_yaml = read_yaml()
for site_dict in parsed_yaml["all"]["sites"]:
for host in site_dict["hosts"]:
device_name = host.get('hostname')
yield device_name
def main():
parsed_yaml = read_yaml()
connection_params = form_connection_params_from_yaml(parsed_yaml)
for device_output in collect_outputs(connection_params, COMMANDS_LIST):
#print(device_output)
print("Capturing output to a file named after device in your local directory")
if __name__ == "__main__":
main()参考https://github.com/rajaramanlala/netmiko-with-dynamic-inventory
https://stackoverflow.com/questions/73155478
复制相似问题