首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python :通过SSH(Paramiko)或TELNET(Telnetlib)从思科交换机获取running_config

Python :通过SSH(Paramiko)或TELNET(Telnetlib)从思科交换机获取running_config
EN

Stack Overflow用户
提问于 2019-11-27 15:00:05
回答 1查看 3K关注 0票数 1

我需要一些关于Python脚本的帮助。它工作了几次,但我只是添加了一些time.sleep(),现在脚本无法工作:它没有通过SSH或Telnet连接到交换机。

我还需要一些技巧来优化它,因为我不是专业的,我想了解更多关于脚本的知识。

谢谢!

(法文评注:/)

代码语言:javascript
运行
复制
import paramiko, time, re, os
from ciscoconfparse import CiscoConfParse
import telnetlib

###cherche hotes depuis fichier hosts.txt###
with open("./hosts/hosts.txt","r") as f:
    hosts = re.findall(r'(\d+.\d+.\d+.\d+)', f.read())
    f.close()
###boucle pour chaque hotes###
for host in hosts:
    state = ""
    running_config = ""
    try:
        ###Connexion SSH switch###
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(host, username='admin', password='XXXXX')
        ###création shell interactif###
        connection = client.invoke_shell()
        ###commande enable###
        connection.send("enable\n")
        time.sleep(1)
        connection.send("XXXX\n")
        ###commande running-config###
        connection.send("terminal length 0\n") ###Permet l'affichage de l'intégralité des commande###
        time.sleep(1)
        connection.send("show running-config\n")
        ###récupération commande running-config###
        resp_run = connection.recv(10000).decode(encoding='utf-8')
        ###fermeture sessions SSH###
        connection.close()
        client.close()
        ###Traitement running-config###
        regex = re.compile(r'(Current configuration : (.+\n)+end)')
        res = re.findall (regex, resp_run)
        running_config = res[0][0] ###aide appel variable
    except:
        ###si fail SSH test telnet###
        state = "SSH NOK "###Permet génération rapport###
        try:
            ###connexion telnet si SSH NOK###
            session = telnetlib.Telnet(host, 23)
            session.write(b"admin\n")
            session.read_until(b"Password: ")
            session.write(b"XXXXXX\n")
            time.sleep(1)
            session.write(b"enable\n")
            session.read_until(b"Password: ")
            session.write(b"XXXXXX\n")
            session.read_until(b"#")
            session.write(b"term len 0\n")
            session.write(b"show run\n")
            res = session.read_until(b"\nend").decode('utf-8')
            ###fermeture session telnet###
            session.close()
            ###récupération commande running-config###
            regex = re.compile(r'(Current configuration : (.+\n)+end)')
            res = re.findall(regex, res)
            running_config = res[0][0] ###aide appel variable###
        except:
            state += "TELNET NOK"###Permet génération rapport###

    ###Création fichier running_config.txt + dir selon host###
    newpath = ('./config_switch/'+host+'/')
    if not os.path.exists(newpath):
        os.makedirs(newpath)
    f = open("./config_switch/"+host+"/running_config.txt", "w+")
    f.write(running_config)
    f.close()
    ###test ssh telnet pour rapport###
    if not state:
        print (host+" OK")
    else:
        print (host+" : "+state+" ERREUR")

    ###generation rapport###    
    f = open("./rapport.txt","a")
    f.write(state)
    f.close()
    ###arrêt de 2sec par sécurité###
    time.sleep(2)
EN

回答 1

Stack Overflow用户

发布于 2019-11-30 22:00:14

如果您的网络中有不同的版本/模型设备,那么您应该有一个很好的错误处理机制。因此,我们使用下面的函数来进行一些操作,这些操作可能会对您有所帮助。

代码(SSH连接):

代码语言:javascript
运行
复制
#Make Connection To Device Through SSH (If returns None Do Not Proceed)
def connectToCPESSH(ip, uname, pin, CI_LOCAL_ID, CI_Name, CI_Org_Name, runIDnull):
    ip =  ip.strip()
    SSHCliente = None
    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(ip, port=22, username=uname, password=pin, 
                       timeout=240,banner_timeout=250, auth_timeout=500)
        SSHCliente = client.invoke_shell()
        return SSHCliente
    except paramiko.ssh_exception.SSHException as ssh1Err:
        return "Equipment SSH version error : " + str(ssh1Err)
        if isinstance(SSHCliente, paramiko.channel.Channel):
            SSHCliente.close()
        sys.exit()
        return None
    except Exception as e:
        if isinstance(SSHCliente, paramiko.channel.Channel):
            SSHCliente.close()
        try:
            tln = telnetlib.Telnet(ip)
            print("Use Telnet Access to " + str(e) + " ### " + str(t))
        except Exception as t:
            print("Crab! Both Telnet and SSH Connection Failed ! " + str(e) + " ### " + str(t))
        return None

因此,在上面的代码中,我们尝试通过SSH进行连接,如果我们得到一个关于SSHException的错误,我们记录它,如果我们得到任何错误,尝试Telnet (这是可选的,我们对一些旧设备使用Telnet )。

代码(等待提示:只有HW和Cisco)

代码语言:javascript
运行
复制
#Wait Prompt For The First Connection
def waitForPrompt(cxn):
    appendedScrnRslt = ""
    lastScrnRslt = ""
    routerType = ""
    outerLoop = True
    timerx = 0
    while outerLoop == True:
        tempScrn = cxn.recv(65100).decode('ascii')
        if(lastScrnRslt != tempScrn):
            appendedScrnRslt += tempScrn
            lastScrnRslt = tempScrn
        if("#" in tempScrn or ">" in tempScrn or "]" in tempScrn):
            if("#" in tempScrn):
                routerType = "Cisco"
            if(("<" in tempScrn  and ">" in tempScrn) or ("[" in tempScrn  and "]" in tempScrn) ):
                routerType = "Huawei"
            break
        timerx += 1
        if(timerx >= 100):
            logging.warn("Uppss! No Connection")
            routerType = "N/A"
            break
    return routerType

等待提示是正式的,如果您动作早,您的命令将不会发送到设备,如果您执行得晚,您的cxn可能会被终止。所以,只要检查提示符(HW:,Cisco:您的路由器名称#)就更好了.

代码(收发):

代码语言:javascript
运行
复制
#Send Command and Recevie CIdatafromSQL
def sendCmdToSSH(cxn, cmd, routerType, timeout):
    appendedScrnRslt = ""
    lastScrnRslt = ""
    cxn.send(bytes(cmd+ "\x0D", 'utf-8'))
    time.sleep(2)
    timery = time.perf_counter()
    while time.perf_counter() - timery <= timeout:
        if(routerType == "Cisco"):
            tempScrn = cxn.recv(65100).decode('ascii')
            if(lastScrnRslt != tempScrn):
                appendedScrnRslt += tempScrn
                lastScrnRslt = tempScrn
            arrTmp = tempScrn.split('\r\n')
            arrTmp.reverse()
            if("#" in arrTmp[0]):
                break
            arrTmp = []
        if(routerType == "Huawei"):
            tempScrn = cxn.recv(65100).decode('ascii')
            if(lastScrnRslt != tempScrn):
                appendedScrnRslt += tempScrn
                lastScrnRslt = tempScrn
            arrTmp = tempScrn.split('\r\n')
            arrTmp.reverse()
            if(">" in arrTmp[0] or "]" in arrTmp[0] ):
                break
            arrTmp = []
    return appendedScrnRslt

发送和接收需要一个超时,以便中断连接,如果发生某些错误,我们肯定需要屏幕结果。

代码(从思科获得所有运行的Config ):

代码语言:javascript
运行
复制
singleSSHCxn = connectToCPESSH(ip, uname, pin, CI_LOCAL_ID, CI_Name,
                               CI_Org_Name, runIDnull) 
sendCmdToSSH(singleSSHCxn, "terminal length 0", "Cisco", 120)
cliResult = sendCmdToSSH(singleSSHCxn, "show running-config", "Cisco", 200)
sendCmdToSSH(singleSSHCxn, "exit", "Cisco", 120)

希望这能解决你的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59073011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档