PHP前端开发

图文详解python之简单主机批量管理工具

百变鹏仔 2个月前 (02-08) #Python
文章标签 管理工具

 今天做了一个很简单的小项目,感受到了paramiko模块的强大,也深感自己linux的功力不行~~

一、需求

二、简单需求分析及流程图


需求很少,我就简单地说下:
1. 主机分组可以配置文件实现(我用字典存数据的).
2. 登陆功能不做。选择分组后可查看组内对应主机的主机名和IP地址.
3. >>>cmd: df(输入命令则起多个线程(视组内有多少个主机而定)同时执行)
  输出:
  -------------h1------------
  ……(命令返回的数据)
  -------------h2------------
  ……
  >>>put  test.yy(本地文件)   filename (把本地的test.yy文件传到远程主机的/root目录下)
4.可写在配置文件中。包括远程主机的: 主机名 IP  用户名  密码 端口

 

流程图

立即学习“Python免费学习笔记(深入)”;

 

三、目录结构及源代码

目录结构:

from_windows.py(待上传的文件)

main.py(批量主机管理接口)

"""批量主机管理接口"""import coreif name == "main":    core.run()

core.py(核心代码,被接口调用)

"""核心代码"""import settingsimport paramikoimport threadingimport osclass REMOTE_HOST(object):    #远程操作主机    def init(self, host, port ,username, password, cmd):        self.host = host        self.port = port        self.username = username        self.password = password        self.cmd = cmd    def run(self):        """起线程连接远程主机后调用"""        cmd_str = self.cmd.split()[0]        if hasattr(self, cmd_str):      #反射 eg:调用put方法            getattr(self, cmd_str)()        else:            #setattr(x,'y',v)is  equivalent  to   ``x.y=v''            setattr(self, cmd_str, self.command)            getattr(self, cmd_str)()  #调用command方法,执行批量命令处理    def command(self):        """批量命令处理"""        ssh = paramiko.SSHClient()  #创建ssh对象        #允许连接不在know_hosts文件中的主机        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())        ssh.connect(hostname=self.host,port=self.port,username=self.username,password=self.password)        stdin,stdout,stderr = ssh.exec_command(self.cmd)        result = stdout.read()        print("%s".center(50, "-") % self.host)        print(result.decode())        ssh.close()    def put(self):        """上传文件"""        filename = 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)        sftp.put(filename, filename)        print("put sucesss")        transport.close()def show_host_list():    """通过选择分组显示主机名与IP"""    for index, key in enumerate(settings.msg_dic):        print(index + 1, key, len(settings.msg_dic[key]))    while True:        choose_host_list = input(">>>(eg:group1)").strip()        host_dic = settings.msg_dic.get(choose_host_list)        if host_dic:            #print(host_dic)            for key in host_dic:                print(key, host_dic[key]["IP"])            return host_dic        else:            print("NO exit this group!")def interactive(choose_host_list):    """根据选择的分组主机起多个线程进行批量交互"""    thread_list = []    while True:        cmd = input(">>>").strip()        if cmd:            for key in choose_host_list:                host, port, username, password = choose_host_list[key]["IP"], choose_host_list[key]["port"],                                                  choose_host_list[key]["username"], choose_host_list[key]["password"]                func = REMOTE_HOST(host, port, username, password, cmd)  # 实例化类                t = threading.Thread(target=func.run)  # 起线程                t.start()                thread_list.append(t)            for t in thread_list:                t.join()  # 主线程等待子线程执行完毕        else:            continuedef run():    choose_host_list = show_host_list()    interactive(choose_host_list)

settings.py(配置文件)

"""配置文件"""msg_dic = {    "group1":{    #分组1        "h1":{"IP":"192.168.1.1", "username":"11", "password":"aa", "port":22},        "h2":{"IP":"192.168.1.2", "username":"22", "password":"bb", "port":22},        "h3":{"IP":"192.168.1.3", "username":"33", "password":"cc", "port":22},        "h4":{"IP":"192.168.1.4", "username":"44", "password":"dd", "port":22},        "h5":{"IP":"192.168.1.5", "username":"55", "password":"ee", "port":22},        "h6":{"IP":"192.168.1.6", "username":"66", "password":"ff", "port":22},    },    "group2":{    #分组2        "h1":{"IP":"192.168.2.1", "username":"111", "password":"aaa", "port":22},        "h2":{"IP":"192.168.2.2", "username":"222", "password":"bbb", "port":22},        "h3":{"IP":"192.168.2.3", "username":"333", "password":"ccc", "port":22},        "h4":{"IP":"192.168.2.4", "username":"444", "password":"ddd", "port":22},        "h5":{"IP":"192.168.2.5", "username":"555", "password":"eee", "port":22},        "h6":{"IP":"192.168.2.6", "username":"666", "password":"fff", "port":22},        "h7":{"IP":"192.168.2.7", "username":"777", "password":"ggg", "port":22},        "h8":{"IP":"192.168.2.8", "username":"888", "password":"hhh", "port":22},    },    "group3":{        "h1":{"IP":"192.168.179.133", "username":"root", "password":"zcl", "port":22},    }}

测试:

硬件限制,我只用连接一台虚拟机测试~

C:Python34python3.exe C:/Users/Administrator/PycharmProjects/laonanhai/host_manage/main.py1 group1 62 group3 13 group2 8>>>(eg:group1)group3h1 192.168.179.133>>>put from_windows.pyput sucesss>>>>>>ls------------------------192.168.179.133------------------------anaconda-ks.cfgdatabase_testfrom_windows.pyinstall.loginstall.log.syslogmootoottmprom_windows.py>>>

上传前没有from_windows.py文件,上传后就有了!