zoukankan      html  css  js  c++  java
  • python之简单主机批量管理工具

    转发注明出处:http://www.cnblogs.com/0zcl/p/6352278.html 

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

    一、需求

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


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

    流程图

    我做的流程图https://www.processon.com/diagraming/588a1219e4b087b11659068b

    三、目录结构及源代码

    目录结构:

    from_windows.py(待上传的文件)

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

    1 """批量主机管理接口"""
    2 
    3 import core
    4 
    5 if __name__ == "__main__":
    6     core.run()
    View Code

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

     1 """核心代码"""
     2 import settings
     3 import paramiko
     4 import threading
     5 import os
     6 
     7 
     8 class REMOTE_HOST(object):
     9     #远程操作主机
    10     def __init__(self, host, port ,username, password, cmd):
    11         self.host = host
    12         self.port = port
    13         self.username = username
    14         self.password = password
    15         self.cmd = cmd
    16 
    17     def run(self):
    18         """起线程连接远程主机后调用"""
    19         cmd_str = self.cmd.split()[0]
    20         if hasattr(self, cmd_str):      #反射 eg:调用put方法
    21             getattr(self, cmd_str)()
    22         else:
    23             #setattr(x,'y',v)is  equivalent  to   ``x.y=v''
    24             setattr(self, cmd_str, self.command)
    25             getattr(self, cmd_str)()  #调用command方法,执行批量命令处理
    26 
    27     def command(self):
    28         """批量命令处理"""
    29         ssh = paramiko.SSHClient()  #创建ssh对象
    30         #允许连接不在know_hosts文件中的主机
    31         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    32         ssh.connect(hostname=self.host,port=self.port,username=self.username,password=self.password)
    33         stdin,stdout,stderr = ssh.exec_command(self.cmd)
    34         result = stdout.read()
    35         print("%s".center(50, "-") % self.host)
    36         print(result.decode())
    37         ssh.close()
    38 
    39     def put(self):
    40         """上传文件"""
    41         filename = self.cmd.split()[1]  #要上传的文件
    42         transport = paramiko.Transport((self.host, self.port))
    43         transport.connect(username=self.username, password=self.password)
    44         sftp = paramiko.SFTPClient.from_transport(transport)
    45         sftp.put(filename, filename)
    46         print("put sucesss")
    47 
    48         transport.close()
    49 
    50 
    51 def show_host_list():
    52     """通过选择分组显示主机名与IP"""
    53     for index, key in enumerate(settings.msg_dic):
    54         print(index + 1, key, len(settings.msg_dic[key]))
    55     while True:
    56         choose_host_list = input(">>>(eg:group1)").strip()
    57         host_dic = settings.msg_dic.get(choose_host_list)
    58         if host_dic:
    59             #print(host_dic)
    60             for key in host_dic:
    61                 print(key, host_dic[key]["IP"])
    62             return host_dic
    63         else:
    64             print("NO exit this group!")
    65 
    66 
    67 def interactive(choose_host_list):
    68     """根据选择的分组主机起多个线程进行批量交互"""
    69     thread_list = []
    70     while True:
    71         cmd = input(">>>").strip()
    72         if cmd:
    73             for key in choose_host_list:
    74                 host, port, username, password = choose_host_list[key]["IP"], choose_host_list[key]["port"], 
    75                                                  choose_host_list[key]["username"], choose_host_list[key]["password"]
    76                 func = REMOTE_HOST(host, port, username, password, cmd)  # 实例化类
    77                 t = threading.Thread(target=func.run)  # 起线程
    78                 t.start()
    79                 thread_list.append(t)
    80             for t in thread_list:
    81                 t.join()  # 主线程等待子线程执行完毕
    82         else:
    83             continue
    84 
    85 
    86 def run():
    87     choose_host_list = show_host_list()
    88     interactive(choose_host_list)

    settings.py(配置文件)

     1 """配置文件"""
     2 
     3 msg_dic = {
     4     "group1":{    #分组1
     5         "h1":{"IP":"192.168.1.1", "username":"11", "password":"aa", "port":22},
     6         "h2":{"IP":"192.168.1.2", "username":"22", "password":"bb", "port":22},
     7         "h3":{"IP":"192.168.1.3", "username":"33", "password":"cc", "port":22},
     8         "h4":{"IP":"192.168.1.4", "username":"44", "password":"dd", "port":22},
     9         "h5":{"IP":"192.168.1.5", "username":"55", "password":"ee", "port":22},
    10         "h6":{"IP":"192.168.1.6", "username":"66", "password":"ff", "port":22},
    11     },
    12 
    13     "group2":{    #分组2
    14         "h1":{"IP":"192.168.2.1", "username":"111", "password":"aaa", "port":22},
    15         "h2":{"IP":"192.168.2.2", "username":"222", "password":"bbb", "port":22},
    16         "h3":{"IP":"192.168.2.3", "username":"333", "password":"ccc", "port":22},
    17         "h4":{"IP":"192.168.2.4", "username":"444", "password":"ddd", "port":22},
    18         "h5":{"IP":"192.168.2.5", "username":"555", "password":"eee", "port":22},
    19         "h6":{"IP":"192.168.2.6", "username":"666", "password":"fff", "port":22},
    20         "h7":{"IP":"192.168.2.7", "username":"777", "password":"ggg", "port":22},
    21         "h8":{"IP":"192.168.2.8", "username":"888", "password":"hhh", "port":22},
    22     },
    23 
    24     "group3":{
    25         "h1":{"IP":"192.168.179.133", "username":"root", "password":"zcl", "port":22},
    26     }
    27 }
    View Code

    测试:

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

    C:Python34python3.exe C:/Users/Administrator/PycharmProjects/laonanhai/host_manage/main.py
    1 group1 6
    2 group3 1
    3 group2 8
    >>>(eg:group1)group3
    h1 192.168.179.133
    >>>put from_windows.py
    put sucesss
    >>>
    >>>ls
    ------------------------192.168.179.133------------------------
    anaconda-ks.cfg
    database_test
    from_windows.py
    install.log
    install.log.syslog
    m
    oot
    
    oot
    tmpfrom_windows.py
    
    >>>

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

     

    PS:关于paramiko模块可以看看这篇博客http://www.cnblogs.com/starof/p/4670433.html

  • 相关阅读:
    [LeetCode]题解(python):119-Pascal's Triangle II
    [LeetCode]题解(python):118-Pascal's Triangle
    [LeetCode]题解(python):117-Populating Next Right Pointers in Each Node II
    寒假自学进度8
    寒假自学进度7
    寒假自学进度6
    寒假自学5
    寒假自学学习4
    寒假自学进度3
    寒假自学进度2
  • 原文地址:https://www.cnblogs.com/0zcl/p/6352278.html
Copyright © 2011-2022 走看看