作业:
简单的主机批量管理工具
需求:
1. 主机分组;
2. 登陆后显示主机分组,选择分组后查看主机列表
3. 可以批量执行命令,发送文件,结果实时返回
4. 主机用户名密码可以不同
目录结构:
├── bin
│ ├── host-manager.py
│ └── __init__.py
├── conf
│ ├── __init__.py
│ └── settings.py
├── core
│ ├── common_func.py
│ ├── __init__.py
│ ├── main.py
│ └── __pycache__
│ ├── command_func.cpython-36.pyc
│ ├── common_func.cpython-36.pyc
│ ├── __init__.cpython-36.pyc
│ └── main.cpython-36.pyc
├── data
│ ├── create_data.py
│ ├── group_data.json
│ ├── host_data.json
│ └── __init__.py
├── __init__.py
└── logs
└── __init__.py
1. host-manager.py
# Author:Brace Li
import os,sys
# import base dir to environment var
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
import os,sys
# import base dir to environment var
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from core import main
if __name__ == "__main__":
main.main()
main.main()
2. main.py
# Author:Brace Li
from core import common_func
import paramiko
import sys
import threading
import paramiko
import sys
import threading
class MyThread(threading.Thread):
def __init__(self, func, args):
super(MyThread, self).__init__()
self.func = func
self.args = args
self.result = self.func(*self.args)
def getresult(self):
try:
return self.result
except Exception:
return None
def __init__(self, func, args):
super(MyThread, self).__init__()
self.func = func
self.args = args
self.result = self.func(*self.args)
def getresult(self):
try:
return self.result
except Exception:
return None
class Host(object):
def __init__(self, hostname, username, password, port):
self.hostname = hostname
self.username = username
self.password = password
self.port = port
def __init__(self, hostname, username, password, port):
self.hostname = hostname
self.username = username
self.password = password
self.port = port
def login(self):
print("self.hostname:", self.hostname)
print("self.username:", self.username)
print("self.password:", self.password)
print("self.port:", self.port)
print("self.hostname:", self.hostname)
print("self.username:", self.username)
print("self.password:", self.password)
print("self.port:", self.port)
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password)
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password)
def command(self, cmd):
stdin, stdout, stderr = self.ssh.exec_command(cmd)
if stdout:
result = stdout.read()
else:
result = stderr.read()
return result.decode()
stdin, stdout, stderr = self.ssh.exec_command(cmd)
if stdout:
result = stdout.read()
else:
result = stderr.read()
return result.decode()
def exit(self):
self.ssh.close()
self.ssh.close()
def main():
common_func.show_system_info()
res = common_func.input_check(">>", (1, 2, 3), "T")
if res == 1:
file = "D:/Python3/python_project/Project_1/host-management/data/host_data.json"
host_data = common_func.get_data_from_db(file)
host_menu = []
host_id = []
for n in host_data.keys():
host_menu.append(n)
for k, v in enumerate(host_menu, 1):
host_id.append(k)
print("%s - %s" % (k, v))
print("*" * 80)
host_sel = common_func.input_check(" 请选择主机:", tuple(host_id), "T")
host_info = host_data[host_menu[host_sel - 1]]
print(host_info)
host = Host(host_info['address'], host_info['username'], host_info['password'], host_info['port'])
host.login()
while True:
host_cmd = common_func.input_check(">>", (), "F")
if host_cmd == "exit":
host.exit()
break
else:
host_response = host.command(host_cmd)
print(host_response)
elif res == 2:
file = "D:/Python3/python_project/Project_1/host-management/data/group_data.json"
group_data = common_func.get_data_from_db(file)
file1 = "D:/Python3/python_project/Project_1/host-management/data/host_data.json"
host_data = common_func.get_data_from_db(file1)
group_menu = []
group_id = []
for n in group_data.keys():
group_menu.append(n)
for k, v in enumerate(group_menu, 1):
group_id.append(k)
print("%s - %s" % (k, v))
print("*" * 80)
group_sel = common_func.input_check(" 请主机组:", tuple(group_id), "T")
groupinfo = group_data[group_menu[group_sel-1]]
print(groupinfo)
common_func.show_system_info()
res = common_func.input_check(">>", (1, 2, 3), "T")
if res == 1:
file = "D:/Python3/python_project/Project_1/host-management/data/host_data.json"
host_data = common_func.get_data_from_db(file)
host_menu = []
host_id = []
for n in host_data.keys():
host_menu.append(n)
for k, v in enumerate(host_menu, 1):
host_id.append(k)
print("%s - %s" % (k, v))
print("*" * 80)
host_sel = common_func.input_check(" 请选择主机:", tuple(host_id), "T")
host_info = host_data[host_menu[host_sel - 1]]
print(host_info)
host = Host(host_info['address'], host_info['username'], host_info['password'], host_info['port'])
host.login()
while True:
host_cmd = common_func.input_check(">>", (), "F")
if host_cmd == "exit":
host.exit()
break
else:
host_response = host.command(host_cmd)
print(host_response)
elif res == 2:
file = "D:/Python3/python_project/Project_1/host-management/data/group_data.json"
group_data = common_func.get_data_from_db(file)
file1 = "D:/Python3/python_project/Project_1/host-management/data/host_data.json"
host_data = common_func.get_data_from_db(file1)
group_menu = []
group_id = []
for n in group_data.keys():
group_menu.append(n)
for k, v in enumerate(group_menu, 1):
group_id.append(k)
print("%s - %s" % (k, v))
print("*" * 80)
group_sel = common_func.input_check(" 请主机组:", tuple(group_id), "T")
groupinfo = group_data[group_menu[group_sel-1]]
print(groupinfo)
obj_cmd = []
for n in groupinfo:
n = Host(host_data[n]['address'], host_data[n]['username'], host_data[n]['password'], host_data[n]['port'])
n.login()
obj_cmd.append(n)
for n in groupinfo:
n = Host(host_data[n]['address'], host_data[n]['username'], host_data[n]['password'], host_data[n]['port'])
n.login()
obj_cmd.append(n)
while True:
host_cmd = common_func.input_check(">>", (), "F")
if host_cmd == "exit":
for n in obj_cmd:
n.exit()
break
else:
xx = []
yy = []
for n in obj_cmd:
t = MyThread(n.command, args=(host_cmd,))
t.start()
xx.append(t)
for x in xx:
x.join()
yy.append(x.getresult())
for n in yy:
print("====================")
print(n)
else:
sys.exit("系统退出......!")
host_cmd = common_func.input_check(">>", (), "F")
if host_cmd == "exit":
for n in obj_cmd:
n.exit()
break
else:
xx = []
yy = []
for n in obj_cmd:
t = MyThread(n.command, args=(host_cmd,))
t.start()
xx.append(t)
for x in xx:
x.join()
yy.append(x.getresult())
for n in yy:
print("====================")
print(n)
else:
sys.exit("系统退出......!")
3. common_func.py
# Author:Brace Li
import json
import json
def show_error(err):
print("Error:%s" % err)
print("Error:%s" % err)
def get_data_from_db(file):
"""
get data from data base;
:param file: database
:return:
"""
#file = "host_data.json"
with open(file, "r") as f:
data = json.load(f)
return data
"""
get data from data base;
:param file: database
:return:
"""
#file = "host_data.json"
with open(file, "r") as f:
data = json.load(f)
return data
def show_system_info():
"""
only for first page to show system info.
:return:
"""
print("*" * 80)
print("*%s*" % "".center(78))
print("*%s*" % ">>>>> 主 机 集 中 管 理 <<<<<".center(72))
print("*%s*" % "Ver:1.00".center(78))
print("*%s*" % "".center(78))
print("*" * 80)
print("*%s*" % " >> 入口: 1.主机列表, 2.主机组列表, 3.退出".ljust(65))
print("*" * 80)
"""
only for first page to show system info.
:return:
"""
print("*" * 80)
print("*%s*" % "".center(78))
print("*%s*" % ">>>>> 主 机 集 中 管 理 <<<<<".center(72))
print("*%s*" % "Ver:1.00".center(78))
print("*%s*" % "".center(78))
print("*" * 80)
print("*%s*" % " >> 入口: 1.主机列表, 2.主机组列表, 3.退出".ljust(65))
print("*" * 80)
def input_check(prompt_msg, check_range, flag):
"""
校验输入正确性, eg: input_check("select action:", (1, 2), "T")
:param prompt_msg: 输入提示信息
:param check_range: check range, if it is none, use "()" instead
:param flag: number or string, T is for int number, F is anything
:return: the value of input.
"""
while True:
data = input(prompt_msg).strip()
if not data:
show_error("input is null!")
continue
if flag == "T":
if data.isdigit():
data = int(data)
else:
show_error("data's type is invalid !")
continue
if data.isdigit():
data = int(data)
else:
show_error("data's type is invalid !")
continue
if check_range:
if data in check_range:
break
else:
show_error("Invalid input!")
continue
else:
break
return data
if data in check_range:
break
else:
show_error("Invalid input!")
continue
else:
break
return data
4. group_data.json
{"Web-Server": ["host1", "host2", "host3"], "Data-Server": ["host3", "host4"]}
5. host_data.json
{"host1": {"hostname": "Web-Server-1", "address": "192.168.137.10", "username": "brace", "password": "123456", "port": 22}, "host2": {"hostname": "Web-Server-2", "address": "192.168.137.11", "username": "brace", "password": "123456", "port": 22}, "host3": {"hostname": "data-Server-3", "address": "192.168.137.12", "username": "brace", "password": "123456", "port": 22}, "host4": {"hostname": "data-Server-1", "address": "192.168.137.13", "username": "brace", "password": "123456", "port": 22}}