类似fabric主机管理demo

类似于fabric的主机管理系统

可以批量对主机进行操作

  • 批量上传文件
  • 批量下载文件
  • 批量执行命令

demo代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author : Leon
# Date 2017/6/27


import threading
import paramiko
from conf import HOST_MAP
lock = threading.Lock()

class MyFabric(object):
    '''MyFabric'''
    def __init__(self):
        self.show()
        self.run()

    def run(self):
        while True:
            ChoiceList = input("请输入选择的主机编号,一个或多个,多个请空格隔开,一个组请以group作为关键字开始[exit退出]:").strip().split()
            if ChoiceList[0] == "exit":
                exit("Bye")
            elif ChoiceList[0] == "group":
                self.ChoiceHost = []  #清空
                GroupName = ChoiceList[1]
                for host in HOST_MAP:
                    if HOST_MAP[host]["group"] == GroupName:
                        self.ChoiceHost.append(host)
                print("经过输入帅选,确认选择的主机以及编号".center(25, '#'))

                for index in self.ChoiceHost:
                    print("[{host}]".format(host=index))
                confirm = input("请确认[yes/no]:").strip().lower()
                if confirm:
                    if confirm == "yes":
                        # 选择想要执行的动作
                        action = input("请输入想要执行的动作(put/get/cmd):").strip()
                        if hasattr(self, action):
                            func = getattr(self, action)
                            func()
                            print("33[36mThe End33[0m".center(30, '-'))
                    elif confirm == "no":
                        continue
            else:
                self.ChoiceHost = []
                for item in self.IndexHOST_MAP:
                    if str(self.IndexHOST_MAP[item]["index"]) in ChoiceList:
                        self.ChoiceHost.append(item)
                print("经过输入帅选,确认选择的主机以及编号".center(25, '#'))
                for index in self.ChoiceHost:
                    print("[{host}]".format(host=index))
                confirm = input("请确认[yes/no]:").strip().lower()
                if confirm:
                    if confirm == "yes":
                        # 选择想要执行的动作
                        action = input("请输入想要执行的动作(put/get/cmd):").strip()
                        if hasattr(self, action):
                            func = getattr(self, action)
                            func()
                            print("33[36mThe End33[0m".center(30, '-'))
                    elif confirm == "no":
                        continue


    def show(self):
        self.IndexHOST_MAP = HOST_MAP
        print("33[32mhost list33[0m".center(20, '-'))
        for index,host in enumerate(HOST_MAP):
            print("[{index}]:{host}".format(index=index, host=host))
            self.IndexHOST_MAP[host]["index"] = index  #添加一个index字段



    def _put_file(self,host,port,user,password,LocalPath,ServerPath):
        try:
            t = paramiko.Transport((host,port))
            t.connect(username=user, password=password)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.put(LocalPath, ServerPath)
            t.close()
            print("33[32m从[{host}]上传成功!33[0m".format(host=host))
            return True

        except Exception as e:
            print(e)
            print("33[31m从[{host}]上传失败!33[0m".format(host=host))
            return False

    def _get_file(self,host,port,user,password,ServerPath,LocalPath):
        try:
            t = paramiko.Transport((host, port))
            t.connect(username=user, password=password)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.get(ServerPath, LocalPath)
            t.close()
            print("33[32m从[{host}]下载成功!33[0m".format(host=host))
            return True
        except Exception as e:
            print(e)
            print("33[31m从[{host}]下载失败!33[0m".format(host=host))
            return False

    def _exec_command(self,host,port,user,password,command):
        lock.acquire()
        try:
            ssh_client = paramiko.SSHClient()
            ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh_client.connect(host, port, user, password)
            std_in, std_out, std_err = ssh_client.exec_command(command)
            print("33[32m[{host}]命令执行成功33[0m".format(host=host))
            for line in std_out:
                print(line.strip("
"))
            ssh_client.close()
        except Exception as e:
            print(e)
            print("33[31m[{host}]命令执行失败33[0m".format(host=host))
        lock.release()


    def get(self):
        ServerPath = input("请输入需要批量下载的远程文件文件名[eg:/etc/passwd]:").strip()
        LocalPath = input("请输入文件本地存放的目录以及文件名[eg:/home/passwd]:").strip()
        ThreadList = []
        for item in self.ChoiceHost:
            t = threading.Thread(target=self._get_file,args=(item,
                                                             HOST_MAP[item]["port"],
                                                             HOST_MAP[item]["username"],
                                                             HOST_MAP[item]["password"],
                                                             ServerPath,LocalPath+"_from_"+item,))
            ThreadList.append(t)
        for t in ThreadList:
            t.start()
            t.join()


    def put(self):
        LocalPath = input("请输入需要上传的本地文件地址[eg:/home/passwd]:").strip()
        ServerPath = input("请输入远程存放目录以及文件名[eg:/etc/passwd]").strip()
        ThreadList = []
        for item in self.ChoiceHost:
            t = threading.Thread(target=self._put_file, args=(item,
                                                              HOST_MAP[item]["port"],
                                                              HOST_MAP[item]["username"],
                                                              HOST_MAP[item]["password"],
                                                              LocalPath,
                                                              ServerPath,))
            ThreadList.append(t)
        for t in ThreadList:
            t.start()



    def cmd(self):
        command = input("请输入需要批量执行的命令:[eg:hostanme]").strip()
        ThreadList = []
        for item in self.ChoiceHost:
            t = threading.Thread(target=self._exec_command, args=(item,
                                                              HOST_MAP[item]["port"],
                                                              HOST_MAP[item]["username"],
                                                              HOST_MAP[item]["password"],
                                                              command,))
            ThreadList.append(t)
        for t in ThreadList:
            t.start()
            t.join()


if __name__ == '__main__':
    obj = MyFabric()

配置文件

HOST_MAP = {
    "10.215.24.30":{
        "port":22,
        "username":"root",
        "password":"123456",
        "group":"test"
    },
    "10.215.24.31":{
        "port":22,
        "username":"root",
        "password":"123456",
        "group":"test1"
    },
    "10.215.24.32": {
        "port": 22,
        "username": "root",
        "password": "123456",
        "group": "test1"
    }
}

涉及的知识点

  • paramiko模块的使用
  • 多线程
  • 反射
原文地址:https://www.cnblogs.com/forsaken627/p/7202069.html