Python ssh、telnet协议连接网络设备或者服务器,输入命令返回的结果是多页内容,获取完整的结果方法(二)

内容给接上篇:Python ssh、telnet协议连接网络设备或者服务器,输入命令返回的结果是多页内容,获取完整的结果方法

2、ssh协议访问远程设备的实现

ssh协议远程访问,用到的是jumpssh第三方包。登陆设备分了2类:
1、不经过跳板机直接登陆目标设备
2、通过跳板机(可能多层)再登陆目标设备

实现逻辑就是构造一个字典,字典key是屏幕上出现的目标字符串的正则表达式,当出现时就输入value。 所以可以匹配多页输出的–More–关键字符,匹配成功输入空格(如果是linux服务器可以直接输入数字,例如1000或者10000,将余下的所有行显示出来

    def run_cmd(
            self,
            cmd,
            username=None,
            raise_if_error=True,
            continuous_output=False,
            silent=False,
            timeout=None,
            input_data=None,
            success_exit_code=0,
            retry=0,
            retry_interval=5,
            keep_retry_history=False
    ):
        """ Run command on the remote host and return result locally

        :param cmd: command to execute on remote host
               cmd can be a str or a list of str
        :param username: user used to execute the command (sudo privilege needed)
        :param raise_if_error:
            if True, raise SSHException when exit code of the command is different from 0
            else just return exit code and command output
        :param continuous_output: if True, print output all along the command is running
        :param silent:
            if True, does not log the command run (useful if sensitive information are used in command)
            if parameter is a list, all strings of the command matching an item of the list will be concealed
            in logs (regexp supported)
        :param timeout: length in seconds after what a TimeoutError exception is raised
        :param input_data:
            key/value dictionary used when remote command expects input from user
            when key is matching command output, value is sent
          ---远程命令需要用户输入时使用的键/值字典
             当键与命令输出匹配时,发送值
        :param success_exit_code: integer or list of integer considered as a success exit code for command run
        :param retry: number of retry until exit code is part of successful exit code list (-1 for infinite retry) or
            RunCmdError exception is raised
        :param retry_interval: number of seconds between each retry
        :param keep_retry_history: if True, all retries results are kept and accessible in return result
            default is False as we don't want to save by default all output for all retries especially for big output
        :raises TimeoutError: if command run longer than the specified timeout
        :raises TypeError: if `cmd` parameter is neither a string neither a list of string
        :raises SSHException: if current SSHSession is already closed
        :raises RunCmdError: if exit code of the command is different from 0 and raise_if_error is True
        :return: a class inheriting from collections.namedtuple containing mainly `exit_code` and `output`
            of the remotely executed command
        :rtype: RunCmdResult

        Usage::
            >>> from jumpssh import SSHSession
            >>> with SSHSession('gateway.example.com', 'my_user', password='my_password') as ssh_session:
            >>> ...     ssh_session.run_cmd('hostname')
            RunSSHCmdResult(exit_code=0, output=u'gateway.example.com')
        """

内部实现是:

if input_data and channel.send_ready():
    # We received a potential prompt.
    # 遍历input_data字典的所有key
    for pattern in input_data.keys(): 
        # pattern text matching current output => send input data
        # re匹配成功就输入对应的value值
        if re.search(pattern, data): 
            channel.send(input_data[pattern] + '\n')

实现的脚本代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from jumpssh import SSHSession
import json,time
from concurrent.futures import ThreadPoolExecutor,as_completed


def ssh_inspection(jump=None,target=None,cmd_list=None):
    """
    ssh协议单台设备执行指令函数
    :param jump: 跳板服务器ip,port,username,password 字典
    :param target: 目标服务器ip,port,username,password 字典
    :param cmd_list: 命令列表
    :return: 命令执行结果列表
    """
    assert isinstance(jump,dict) and isinstance(target,dict)
    hostname = target.get('hostname') or target.get('ip')
    ip = target.get('ip')
    result_content = [format('%s-%s-Results of '%(hostname,ip),'#^99s')+'\n']  # 返回结果列表
    # 没有跳板机情况
    if not jump:
        if not all([target.get('ip'),target.get('port'),target.get('username'),target.get('password'),cmd_list]):
            result_content.append('设备信息缺失,无法连接--Device information is missing, unable to connect.\n')
            return result_content
        else:
            try:
                switch_session = SSHSession(target.get('ip'), target.get('username'),
                                            port=target.get('port'), password=target.get('password'),
                                            auth_timeout=3,timeout=4).open() #timeout 设置tcp连接超时时间
            except Exception as e:
                result_content.append(str(e) +'\n')
                return result_content
            else:
                command_list = cmd_list
                for command in command_list:
                    try:
                        # 结果是多頁返回的情况,比如more打开文本文件,正则匹配输入里面有'More'字符串,就输入'1000\n'
                        # 表示往下跳过1000行。设置超时返回 timeout设置值
                        # result = switch_session.get_cmd_output(command,input_data={'More':'1000\n'},timeout=10)
                        result = switch_session.get_cmd_output(command,input_data={'More':'1000\n'},timeout=10)
                    except Exception as e:
                        result = e
                    result_content.append('-' * 88 + '\n' + format('命令-command:%s ' % command, ' ^88s') +
                                          '\n' + format('结果-result:', ' ^88s') + '\n%s\n' %
                                          result + '-' * 88 + '\n')
                switch_session.close()
        return result_content
    # 通过跳板机跳转情况
    else:
        if not all([jump.get('ip'),jump.get('port'),jump.get('username'),jump.get('password'),
                    target.get('ip'),target.get('port'),target.get('username'),target.get('password'),cmd_list]):
            result_content.append('缺失必传参数--Missing required parameters.\n')
        try:
            server_session = SSHSession(jump.get('ip'), jump.get('username'),
                                        port=jump.get('port'), password=jump.get('password'),
                                        timeout=4,auth_timeout=3).open()
            switch_session = server_session.get_remote_session(target.get('ip'),
                                                               target.get('username'),
                                                               port=target.get('port'),
                                                               password=target.get('password'),
                                                               timeout=4,auth_timeout=3
                                                               )
        except Exception as e:
            result_content.append(str(e)+'\n')
            return result_content
        else:
            command_list = cmd_list
            for command in command_list:
                try:
                    # result = switch_session.get_cmd_output(command)
                    result = switch_session.get_cmd_output(command, input_data={'More': '1000\n'}, timeout=10)
                except Exception as e:
                    result = str(e)
                result_content.append('-' * 88 + '\n' + format('命令-command:%s ' % command, ' ^88s') +
                                      '\n' + format('结果-result:', ' ^88s') + '\n%s\n' %
                                      result + '-' * 88 + '\n')
            # print(result_content)
            server_session.close()
        finally:
            # server_session.close() # TODO 2020年6月3日14:35:31
            pass
        return result_content

def batch_inspection(info_list):
    """
    批量设备
    :param info_list: 设备信息列表,元素是设备信息字典(包含设备信息,跳板信息,命令集信息)
    :return: 所有任务执行结果
    """
    assert isinstance(info_list,list) and info_list
    executor = ThreadPoolExecutor()
    all_task = [executor.submit(
        ssh_inspection(jump=item.get('jump'),
                       target=item.get('target'),
                       cmd_list=item.get('cmd_list')))for item in info_list]
    for future in as_completed(all_task,timeout=60):
        result = future.result()
        print(result)
        yield result

if __name__ == '__main__':
    jump = {
        # 'ip': '10.12.12.12',
        # 'port': 22,
        # 'username': 'root',
        # 'password': '123456'
    }
    target = {
        'ip': '10.12.12.13',
        'port': 22,
        'username': 'root',
        'password': '123456'
    }

    cmd_list = ['python -V','hostname','cd /tmp/ \n pwd \n ls \n ','df -h']
    result = ssh_inspection(jump,target,cmd_list)
    for i in result:
        print(i)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值