【python】堡垒机实列一(多线程,paramiko,configparser模块实践)

本文介绍了如何使用Python的ConfigParser模块读取配置文件,该配置文件包含了多个主机的登录信息。接着,通过Paramiko库实现远程连接,并运用多线程进行操作。代码中定义了一个生成器,但还有优化空间,计划后续继续完善。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,.定义个setting文件夹中包含的配置文件:

[Group1]
h1={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.111.25’,’port’:’22’}
h2={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.110.135’,’port’:’22’}
[Group2]
h1={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.110.136’,’port’:’22’}
h2={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.110.137’,’port’:’22’}
h3={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.110.138’,’port’:’22’}

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author  : jerry
# @Site    : 
# @File    : host_request.py
# @Software: PyCharm
import configparser,paramiko,threading,time
import json


class Hostmange():
    def __init__(self):
        pass


    def ssh_server(self,hostname,port,username,password,cmd="ifconfig|sed -n '2p'|awk '{print $2}'"):
        '''
        通过paramiko跟跟server端建立联系
        :return: 返回cmd命令的结果
        '''
        ssh=paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)#允许连接不在主句的know_hosts文件中
        ssh.connect(hostname=hostname,port=port,username=username,password=password)
        stdin,stdout,stderr=ssh.exec_command(cmd)
        # if not stderr:
        #     result=stdout.read()
        #     return  result
        # else:
        #     print(stderr.read())
        if cmd=="ifconfig|sed -n '2p'|awk '{print $2}'":
            print("\033[46;1m 服务器地址 \033[0m : \033[36;1m %s \033[0m" % stdout.read().decode())
        else:
            print(stdout.read().decode())

    def ftp_server(self):
        pass


    def host_account_return(self):
        '''
        从配置文件中读取的user,passwd,hostip,port
        返回给用户
        :return: 一个迭代器生成 user,passwd,hostip,port
        '''
        config=configparser.ConfigParser()
        config.read('../setting/host_config2')
        config_section=config.sections()

        for i in config_section:
            for j in config.items(section=i):
                host_mess=eval(j[1])                       ##<----------------str转换为dict eval()
                yield host_mess

    def handler(self):
        '''

        :return:
        '''
        for i in self.host_account_return():
            t1 = threading.Thread(target=self.ssh_server, args=(i['hostname'], i['port'], i['username'], i['password']))
            # self.ssh_server(i['hostname'],i['port'],i['username'],i['password'])
            t1.start()
        while True:
            cmd=input("请输入你想执行的命令>>:").strip()
            if not cmd:continue
            time.sleep(1)
            for i in self.host_account_return():
                t1 = threading.Thread(target=self.ssh_server,
                                      args=(i['hostname'], i['port'], i['username'], i['password'],cmd))
                # self.ssh_server(i['hostname'],i['port'],i['username'],i['password'])
                t1.start()


hoster=Hostmange()
list=hoster.host_account_return()
# hoster.ssh_server('192.250.110.136','22','root','dwzqcs')
hoster.handler()

review代码:
1。关于配置文件的设置,用到了configparser模块取读取
配置文件的格式:
h3={‘username’:’root’,’password’:’passwd’,’hostname’:’192.250.110.138’,’port’:’22’}


    def host_account_return(self):
        '''
        从配置文件中读取的user,passwd,hostip,port
        返回给用户
        :return: 一个迭代器生成 user,passwd,hostip,port
        '''
        config=configparser.ConfigParser()
        config.read('../setting/host_config2')
        config_section=config.sections()

        for i in config_section:
            for j in config.items(section=i):
                host_mess=eval(j[1])                       ##<----------------str转换为dict eval()
                yield host_mess

定义一个生成器,让类内部的方法去代用。

这段代码:使用多线城方式启动,目前存在一点点优化,还没有想到优化方法,下次有时间来优化下

def handler(self):
        '''

        :return:
        '''
        for i in self.host_account_return():
            t1 = threading.Thread(target=self.ssh_server, args=(i['hostname'], i['port'], i['username'], i['password']))
            # self.ssh_server(i['hostname'],i['port'],i['username'],i['password'])
            t1.start()
        while True:
            cmd=input("请输入你想执行的命令>>:").strip()
            if not cmd:continue
            time.sleep(1)
            for i in self.host_account_return():
                t1 = threading.Thread(target=self.ssh_server,
                                      args=(i['hostname'], i['port'], i['username'], i['password'],cmd))
                # self.ssh_server(i['hostname'],i['port'],i['username'],i['password'])
                t1.start()

利用多进程的方式,将原来的def handler函数重新封装:

  1.赋值一个变量self.host_accoutn_return迭代器,在函数体内,应为迭代器迭代完之后就不存在
  2,用函数封装,在函数体内去判断(封装的思想)
  3.args返回的是元祖,*args返回的是输入值,建议用*args
  4.启动进程池的方法pool=Pool(5)
                  pool.apply_async(func= , args())

                  pool.apply_async(func=self.ssh_server, args=(i['hostname'], i['port'], i['username'], i['password']))
 def handler(self):
        '''
        1.赋值一个变量self.host_accoutn_return迭代器,在函数体内,应为迭代器迭代完之后就不存在
        2,用函数封装,在函数体内去判断(封装的思想)
        3.args返回的是元祖,*args返回的是输入值,建议用*args
        4.

        :return:
        '''
        def startprocess(*args):
            pool=Pool(5)
            accounts=self.host_account_return()
            for i in accounts:
                if not args :
                    pool.apply_async(func=self.ssh_server, args=(i['hostname'], i['port'], i['username'], i['password']))
                else:
                    pool.apply_async(func=self.ssh_server,args=(i['hostname'], i['port'], i['username'], i['password'],*args))
                    # pool.apply_async(func=self.ssh_server,args=(i['hostname'], i['port'], i['username'], i['password'], args)) #args 跟*args有区别。
            pool.close()
            pool.join()



        startprocess() #打印信息
        while True:
            cmd=input("请输入你想执行的命令>>:").strip()
            if not cmd:continue
            startprocess(cmd)

未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值