今天做了一个很简单的小项目,感受到了paramiko模块的强大,也深感自己Linux的功力不行~~
一、需求
二、简单需求分析及流程图
需求很少,我就简单地说下:
1. 主机分组可以配置文件实现(我用字典存数据的).
2. 登陆功能不做。选择分组后可查看组内对应主机的主机名和IP地址.
3. >>>cmd: df(输入命令则起多个线程(视组内有多少个主机而定)同时执行)
输出:
-------------h1------------
……(命令返回的数据)
-------------h2------------
……
>>>put test.yy(本地文件) filename (把本地的test.yy文件传到远程主机的/root目录下)
4.可写在配置文件中。包括远程主机的: 主机名 IP 用户名 密码 端口
流程图
三、目录结构及源代码
目录结构:
from_windows.py(待上传的文件)
main.py(批量主机管理接口) - """批量主机管理接口"""
-
- import core
-
- if __name__ == "__main__":
- core.run()
复制代码 core.py(核心代码,被接口调用)- """核心代码"""
- import settings
- import paramiko
- import threading
- import os
-
-
- class 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:
- continue
-
-
- def 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:\Python34\python3.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
- \root
- tmp\from_windows.py
-
- >>>
复制代码 上传前没有from_windows.py文件,上传后就有了!
|