作业:
 简单的主机批量管理工具
 需求:
 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)
from core import main
if __name__ == "__main__":
    main.main()
 
2.   main.py
# Author:Brace Li
from core import common_func
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
class Host(object):
    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)
        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)
    def command(self, cmd):
        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()
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)
        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)
        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("系统退出......!")
 
 3.     common_func.py
# Author:Brace Li
import json
def show_error(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
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)

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 check_range:
            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}}
 
posted on 2018-07-10 22:07  仙寓游子  阅读(331)  评论(0编辑  收藏  举报