python多线程实现主机批量管理

主程序

#!/usr/bin/env python
# Time    : 2020-8-11 13:25
# Author  : fockrock
# Email   : fockrock@126.com
# File    : main.py
# Software: PyCharm

import settings
import paramiko
import threading
import os

class Hosts(threading.Thread):
    # 定义远程主机的类
    def __init__(self, host, port, username, password, cmd):
        super(Hosts, self).__init__()
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.cmd = cmd

    def run(self):
        '''启动线程连接远程主机'''
        cmd_command = self.cmd.split()[0]   # 获取命令
        if hasattr(self, cmd_command):  # 类里有这个方法
            getattr(self, cmd_command)()  # 执行方法
        else:
            setattr(self, cmd_command, self.command)  # 没有方法,映射command方法
            getattr(self, cmd_command)()   # 调用command方法


    def command(self):
        '''批量命令处理'''
        ssh = paramiko.SSHClient()    # 创建ssh对象
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)   # 允许连接不在konw_host文件里的主机

        # 连接主机
        ssh.connect(hostname=self.host, port=self.port, username=self.username, password=self.password)
        stdin, stdout, stderr = ssh.exec_command(self.cmd)  # 返回标准输入、输出及错误信息
        res, err = stdout.read(), stderr.read()
        result = res if res else err   # 有命令执行结果,返回结果,没有打印错误信息
        print("%s".center(50, '-') % self.host)
        print(result.decode())
        ssh.close()

    def put(self):
        '''文件上传方法'''
        filemame = self.cmd.split()[1]   # 获取文件名
        transport = paramiko.Transport((self.host, self.port))  # 创建ssh实例
        transport.connect(username=self.username, password=self.password)  # 连接远程主机

        sftp = paramiko.SFTPClient.from_transport(transport)  # 创建ftp对象
        try:
            sftp.put(filemame, "/tmp/fockrock/%s" % filemame)  # 文件上传到fockrock目录
            print("%s 上传成功" % self.port)
        except Exception as e:
            print(e)
        transport.close()

    def get(self):
        '''文件下载方法'''
        filemame = self.cmd.split()[1]
        transport = paramiko.Transport((self.host, self.port))
        transport.connect(username=self.username, password=self.password)

        sftp = paramiko.SFTPClient.from_transport(transport)
        try:
            sftp.get("/tmp/fockrock/%s" % filemame, filemame)
            print("%s 下载成功" % self.port)
        except Exception as e:
            print(e)
        transport.close()

def show_host_list():
    """显示主机分组、主机名及IP"""
    for key in settings.remote_host_dic:  # 打印分组及主机数
        print(key, len(settings.remote_host_dic[key]))

    while True:
        choose_host_group = input("请选择主机分组:>>>").strip()
        choice_dic = settings.remote_host_dic.get(choose_host_group)
        if choice_dic:
            for key in choice_dic:  # 选择的分组存在,打印主机名及IP地址
                print(key, choice_dic[key]['IP'])
            return choice_dic
        else:
            print("没有这个主机组,请重新输入")

def start_thread(choice_dic):
    """为选择的分组所有主机单独开启一个线程"""
    thread_list = []
    while True:
        cmd = input(">>>").strip()
        if cmd:
            for key in choice_dic:  # 获取远程主机地址、端口、用户名、密码
                host, port, username, password = choice_dic[key]["IP"], choice_dic[key]["port"], choice_dic[key]["username"], choice_dic[key]["password"]

                func = Hosts(host, port, username, password, cmd)  # 创建主机类
                func.run()  # 启动线程
            
            for t in thread_list:
                t.join()

        else:
            continue

if __name__ == '__main__':
    choice_dic = show_host_list()
    start_thread(choice_dic)


存储主机分组的文件


remote_host_dic = {
    "group1": {    #分组1
        "h1": {"IP": "192.168.1.3", "username": "root", "password": "123456", "port": 22},
        "h2": {"IP": "192.168.1.4", "username": "root", "password": "123456", "port": 22},
        "h3": {"IP": "192.168.1.5", "username": "root", "password": "123456", "port": 22},
        "h4": {"IP": "192.168.1.6", "username": "root", "password": "123456", "port": 22},

    },

    "group2": {    #分组2
        "h1": {"IP": "192.168.2.1", "username": "root", "password": "aaa", "port": 22},
        "h2": {"IP": "192.168.2.2", "username": "root", "password": "bbb", "port": 22},
        "h3": {"IP": "192.168.2.3", "username": "root", "password": "ccc", "port": 22},
        "h4": {"IP": "192.168.2.4", "username": "root", "password": "ddd", "port": 22},

    }

}

# print(remote_host_dic.get('group1'))

测试
1. 启动程序,打印主机分组和主机数
在这里插入图片描述

2. 输入group3,显示分组3的所有主机
在这里插入图片描述
3. 首先测试执行命令
cd fockrock,发现1.5和1.6没有这个目录
1.5和1.6没有fockrock目录
在这里插入图片描述
创建目录再再执行cd命令
在这里插入图片描述
同时执行两个命令
在这里插入图片描述
4. 测试文件传输
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值