试图使asyncio与telnetlib一起使用

问题描述

我很难让asyncio与telnetlib配合使用来询问一些硬件。

我想我显然不了解asyncio的工作方式,我完全迷失了所有这些。真的不清楚。

我的基本版本(同步)运行良好,但查询设备的完整清单实际上需要6个小时,而且大部分设备都无法响应,因为它们无法到达。

由于Asyncio使我们能够并行化连接,而不必等待每次超时触发,因此我想将代码转换为适当的异步代码而没有成功。

这是我尝试过的:

import telnetlib
import time
import datetime
import asyncio

from env.fonctions import *
from env.variables import *


first_cmds = ['term length 0',\
              'show run',\
              'exit']

#create lists to iterate through
hosts = ['router-1','router-2','router-3','router-4','router-5']

async def main(hosts,user_rw_hw,password_rw_hw,first_cmds):
    class ContinueI(Exception):
        pass

    continue_i = ContinueI()

    for host in hosts:
        print(f'{host} | Trying to connect...')
        try:
            tn = await async_establish_telnet_connexion(user_rw_hw,host,23,0.5,True)
        except:
            continue

        print(f'{host} | Checking if equipment is not Nexus')

        tn.write('show version'.encode('ascii') + b"\n")
        sh_ver = await async_read_telnet_output(tn)
        if 'Nexus' in sh_ver or 'NX-OS' in sh_ver or 'nexus' in sh_ver:
            print(f'{host} | Equipment is Nexus,closing connection...')
            tn.write('exit'.encode('ascii') + b"\n")
            continue

        tn.write(''.encode('ascii') + b"\n")

        try:
            for cmd in first_cmds:
                tn.write(cmd.encode('ascii') + b"\n")
                if not 'exit' in cmd:
                    response = await async_read_telnet_output(tn)
                    if '\r\n% Invalid' in response:
                        print(f'{host} | Commande "{cmd}" pas reconnue')
                        raise continue_i
                else:
                    print(f'{host} | Commands are accepted')
        except ContinueI:
            tn.write(b"exit\n")
            tn.write(b"exit\n")
            print(f'{host} | logout for command not recognized')
            continue


if __name__ == "__main__":
    try:
        loop = asyncio.get_event_loop()
        loop.set_debug(1)
        loop.run_until_complete(main(hosts,first_cmds))

    except Exception as e:
        pass

    finally:
        loop.close()

功能

async def async_read_telnet_output(tn,timeout=2,timestep=0.1):
   timer = 0
   data = b''
   while timer <= timeout:
       new_datas = tn.read_very_eager()
       if len(new_datas) != 0:
           timer = 0
           data += new_datas
       await asyncio.wait(timestep)
       timer += timestep
   return data.decode('utf-8')


async def async_establish_telnet_connexion(user_rw_hw,port=23,timeout=1,debug=False):
   try:
       tn = telnetlib.Telnet(host,port)    # Here I don't kNow how to make it awaitable,if I put await before the IDE said that this method is not an awaitable,btw even if I put an awaitable like "asyncio.sleep" the behavior is still the same so it's not the only point bad
   except:
       if debug == True:
           print(f"{host} | Telnet not responding.")
       raise Exception

   if debug == True:
       print(f"{host} | Telnet is responding.")

   response = loop.create_task(async_read_telnet_output(tn,15))

   if not 'Username:' in response and not 'login' in response:
       if debug == True:
           print(f"{host} | Don't see Username asked by equipment.")
       raise Exception
   else:
       tn.write(user_rw_hw.encode('ascii') + b"\n")

   if debug == True:
       print(f"{host} | Username entered.")

   try:
       await tn.read_until(b"Password: ",timeout)
   except:
       if debug == True:
           print(f"{host} | Don't see Password asked by equipment.")
       raise Exception
   finally:
       tn.write(password_rw_hw.encode('ascii') + b"\n")
       response = await async_read_telnet_output(tn,10)
       if '% Authentication Failed' in response or 'Rejected' in response:
           if debug == True:
               print(f"{host} | Connection Failed bad credentials.")
           raise Exception
       if debug == True:
           print(f"{host} | Connection succeed waiting for commands.")
       return tn

如果有人知道我要失败的地方,我将不胜感激,因为我已经呆了一个星期了……读一些书和youtube tutos,但无济于事。

先谢谢您!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)