欢迎来到 SE!
作为一名网络工程师,我最近也开始使用 Python 进行编程,以更好地支持我自己的内部自动化工作。为了避免处理 CLI 附带的低级 ssh 处理的大量手动工作,我专门关注 SecureCRT 应用程序附带的脚本接口。如果你有 SecureCRT,你可以查看它的脚本功能,它的文档将向你展示如何使用 Python 脚本,如下所示。即使您没有 SecureCRT,您也可以使用以下代码作为如何使用本机 ssh 守护程序将此类脚本组合在一起的一般概述,前提是您单独处理所有低级 SSH/CLI 工作。
我对当前状态的此代码不作任何形式的保证。这是基本测试代码,不用于生产。它可能会破坏您的网络!
你被警告了 :)
# $language = "python"
# $interface = "1.0"
import sys
import re
# Your hosts file should just be a list of IP's, each on its own line
HOSTSFILE = '\path_to\your_hosts_file.txt'
USER = 'username'
PASS = 'password'
ENABLEP = 'enablepassword'
NEW_HELPER_CMD = 'ip helper-address x.x.x.x'
def Wait():
# Wait for a prompt
while True:
if not crt.Screen.WaitForCursor(1):
break
def Get_prompt():
row = crt.Screen.CurrentRow
prompt = crt.Screen.Get(row, 0, row, crt.Screen.CurrentColumn - 1).strip()
return prompt
def Get_list_from_file(file_path):
f = open(file_path, 'r')
hostlist = f.readlines()
f.close()
return hostlist
def Log_in(host):
login_command = '/SSH2 /L {0} /PASSWORD {1} {2}'.format(USER, PASS, host)
try:
crt.Session.Connect(login_command)
crt.Session.Synchronous = True
Wait()
return True
except:
# More specific except clauses needed
# For specific error conditions, add corresponding error messages
return False
def Exec_mode():
prompt = Get_prompt()
tries = 0
# Enter priveleged exec mode if not already there
while tries > 4:
if re.search(r'#$', prompt):
break
elif re.search(r'[>]$', prompt):
crt.Screen.Send('enable\n')
Wait()
prompt = Get_prompt()
if re.search(r'Password:', prompt):
crt.Screen.Send('{0}\n'.format(ENABLEP))
Wait()
elif re.search(r'\)$', prompt):
crt.Screen.Send('end\n')
Wait()
tries += 1
if tries >= 4:
# Add an error code stating that exec_mode failed
return False
else:
return True
def Config_mode():
prompt = Get_prompt()
if re.search(r'#$', prompt):
crt.Screen.Send('config t\n')
Wait()
else:
b = Exec_mode()
if b:
crt.Screen.Send('config t\n')
Wait()
prompt = Get_prompt()
if re.search(r'\)$', prompt):
return True
else:
return False
def Pull_and_parse_config():
Wait()
crt.Screen.Send('term len 0\n')
Wait()
prompt = Get_prompt()
# Output the runnning config
crt.Screen.Send(r'sh running-config\n')
crt.Screen.WaitForString(r'\n')
# Capture config output to string var 'config'
# Note: If there is any duplicate of the 'prompt' string in the config, it will stop the
# capture prematurely
config = crt.Screen.ReadString(prompt)
Wait()
# Split the captured config into a list, containing the interface string, old ip helper string, and
# remaining config. Will capture each interface on the device that currently has an ip helper command
# Note: this only captures the first ip helper command on each interface
configlist = re.split(r'(interface [^\n]+?)\n[^!]*?(ip helper-address .+?)\n', config, flags=re.DOTALL)
if len(configlist) > 1:
configlist.pop(0)
return configlist
else:
# add message stating no interfaces matched
return False
def Update_config(configlist):
# For each interface with an ip helper command, remove old command and add new helper command
while len(configlist) > 2:
int_id = configlist.pop(0)
old_helper_cmd = configlist.pop(0)
if re.search(r'interface .+', int_id) and re.search(r'ip helper-address .+', old_helper_cmd):
Enter_config_mode()
# Here is where you actually update the config
# If you don't want to remove old helper command, remove "no {1}\n" from the following string
crt.Screen.Send('{0}\n no {1}\n {2}\n'.format(int_id, old_helper_cmd, NEW_HELPER_CMD))
Wait()
return True
elif not re.search(r'interface .+', int_id):
# add error message stating invalid interface id
return False
else:
# add error message stating invalid ip helper command
return False
def Main():
hostfile = Get_list_from_file(HOSTSFLIE)
for host in hostfile:
ok = Log_in(host)
if not ok:
# add error message stating login failed
continue
ok = Exec_mode()
if not ok:
# add error message here
continue
configlist = Pull_and_parse_config()
if not configlist:
# add error message stating config capture failed
ok = Update_config(configlist)
if not ok:
# add error message stating config update failed
else:
# add success message stating config on host successfully updated
Main()
您将看到,这涉及大量代码,用于看起来应该很简单的事情,而这仅执行一项特定任务!如果您还是脚本/编程领域的新手,我强烈建议您在尝试在生产网络中实现任何脚本之前咨询更有经验的程序员,尤其是涉及修改配置的任何此类脚本。虽然我从我之前所做的一些工作中改编了这段代码,但我没有对此进行测试,我不能保证其中任何一项都会起作用。尽管如此,这应该为您提供一个良好的起点。祝你好运!