我有下面的脚本,它可以正常工作,但是当我使用for循环读取Cisco设备的状态并使用用户定义的函数send_mail()发送邮件时,我收到的是两封邮件,而不是一封邮件建议获得一封邮件,将不胜感激:
username = 'cisco'
password = 'cisco'
hosts = ['10.0.10.100','10.0.10.101']
platform = 'cisco_ios'
def send_mail():
fromaddr = "@gmail.com"
toaddr = "@hotmail.com"
msg = MIMEMultipart()
msg['From'] = '@gmail.com'
msg['To'] = '@hotmail.com'
msg['Subject'] = "This is Health check"
msg.attach(MIMEText(status, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "password")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
for host in hosts:
#print(host)
connect = ConnectHandler(device_type=platform, ip=host, username=username, password=password)
output = connect.send_command('terminal length 0', expect_string=r'#')
output = connect.send_command('enable',expect_string=r'#')
host_name = connect.send_command('show run | in hostname',expect_string=r'#')
interface_status = connect.send_command(f'show ip int brief',expect_string=r'#')
#print(interface_status)
old_stdout = sys.stdout
interface_result = StringIO()
sys.stdout = interface_result
sys.stdout = old_stdout
data = pd.read_fwf(StringIO(interface_status), widths=[27, 16, 3, 7, 23, 8])
status = " "
for index, row in data.iterrows():
if row[4] == 'administratively down' or row[4] == 'down':
log = (f"\nInterface {row[0]} is down in {host_name}\n")
status += log
bgp_status = connect.send_command('show ip bgp summary | be N',expect_string=r'#')
old_stdout = sys.stdout
bgp_result = StringIO()
sys.stdout = bgp_result
sys.stdout = old_stdout
bgp_data = pd.read_fwf(StringIO(bgp_status), delim_whitespace=True, header=None)
for index, row in bgp_data.iterrows():
if row[9] == 'Down' or row[9] == 'Idle' or row[9] == 'Active':
bgp = (f"\nNeighbor {row[0]} is down in {host_name}\n")
status += bgp
send_mail()
答案 0 :(得分:0)
我想我明白您的问题所在。简而言之,您正在每个send_mail()
循环中调用for
,而实际上您想收集每个主机的状态,然后以一封电子邮件的形式发送最终状态报告。这是一个简短的示例,说明了如何执行此操作-显然,您将必须相应地修改代码。
几点:
传入send_mail
参数,而不是让status
依赖全局status
变量。这有助于将功能彼此分离。
您可能希望收集列表中每个主机的状态,然后在发送状态电子邮件时以逻辑方式组合它们。
字符串连接很慢。最好建立一个字符串列表,然后使用字符串join
函数将它们连接起来。
这是一些示例代码:
hosts = ['10.0.10.100','10.0.10.101']
def send_mail(status=''):
'''A placeholder function for testing'''
print("Sending email:\n{status}".format(status=status))
return
status_for_hosts = []
for host in hosts:
status_list = []
# An example of how you might collect statuses for a host
status_list.append("Host {host_ip} is up".format(host_ip=host))
# Use join() instead of string concatenation
full_status = ''.join(status_list)
status_for_hosts.append(full_status)
send_mail(status='\n'.join(status_for_hosts))