今天做了一个很简单的小项目,感受到了paramiko模块的强大,也深感自己Linux的功力不行~~
一、需求
二、简单需求分析及流程图
需求很少,我就简单地说下:
1. 主机分组可以配置文件实现(我用字典存数据的).
2. 登陆功能不做。选择分组后可查看组内对应主机的主机名和IP地址.
3. >>>cmd: df(输入命令则起多个线程(视组内有多少个主机而定)同时执行)
输出:
-------------h1------------
……(命令返回的数据)
-------------h2------------
……
>>>put test.yy(本地文件) filename (把本地的test.yy文件传到远程主机的/root目录下)
4.可写在配置文件中。包括远程主机的: 主机名 IP 用户名 密码 端口
流程图
三、目录结构及源代码
目录结构:
from_windows.py(待上传的文件)
main.py(批量主机管理接口)
1
2
3
4
5
6
|
"""批量主机管理接口"""
import core
if __name__ = = "__main__" :
core.run()
|
core.py(核心代码,被接口调用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
"""核心代码"""
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(配置文件)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
"""配置文件"""
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 },
}
}
|
测试:
硬件限制,我只用连接一台虚拟机测试~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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文件,上传后就有了!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/0zcl/p/6352278.html