python的综合案例之云主机管理系统

可能用到的参考链接:
1. prettytable模块讲解:https://finthon.com/python-prettytable/
2. re正则表达式模块:https://www.runoob.com/python/python-reg-expressions.html
3. csv模块: https://docs.python.org/zh-cn/3/library/csv.html
4. Windows如何永久修改镜像源:https://www.cnblogs.com/eosclover/p/11254378.html

需求:
1. 云主机的属性包括:主机名,IP地址, CPU, 内存, 磁盘类型,磁盘大小,运行状态
2. 云主机的方法包括: 开机,关机,重启
3. 请支持云主机的(增)删改(查)操作,查看云主机信息时,请支持表格查看
4. 支持存储云主机到csv文件中,也支持加载csv文件的云主机信息

分析:
以上需求可以抽象出云主机类(属性+方法), 云主机管理类(属性+方法)
data/machines.csv内需要有表头

hostname,IP

代码







import re
import time
import prettytable as pt
import pandas as pd

FILENAME = 'data/machines.csv'


class Machine:
    """
    云主机类
    1. 云主机的属性包括:主机名,IP地址, CPU, 内存, 磁盘类型,磁盘大小,运行状态
    2. 云主机的方法包括: 开机,关机,重启
    """

    def __init__(self, hostname: str, IP: str, CPU: int = 2, memeory: int = 4,
                 diskCategory: str = '普通云盘', diskSize: int = 40, status: str = 'Running', **kwargs):
        # 将对象self和属性封装在一起
        self.hostname = hostname
        self.IP = IP
        self.CPU = CPU
        self.memory = memeory
        self.diskCategory = diskCategory
        self.diskSize = diskSize
        self.status = status

    def isRunning(self):
        return self.status == 'Running'

    def isStopped(self):
        return self.status == 'Stopped'

    def start(self):
        if self.isRunning():
            return '已开机'
        else:
            print(f'云主机{self.IP}正在开机')
            time.sleep(0.3)
            return '开机成功'

    def stop(self):
        if self.isStopped():
            return '已关机'
        else:
            print(f'云主机{self.IP}正在关机')
            time.sleep(0.3)
            return '关机成功'

    def reboot(self):
        self.stop()
        self.start()
        return '重启成功'

    def to_dict(self):
        """
        将machine对象转成自定义的字典格式
        :return:
        """
        return {
            'hostname': self.hostname,
            'IP': self.IP,
            'CPU': self.CPU,
            'memory': self.memory,
            'diskCategory': self.diskCategory,
            'diskSize': self.diskSize,
            'status': self.status
        }

    def __str__(self):
        """将对象转成字符串时,自动执行该方法"""
        return f'Machine-<{self.hostname}>'

    def __repr__(self):
        """将对象转成字符串时,自动执行该方法"""
        return f'Machine-<{self.hostname}>'


class MachineManager:
    def __init__(self, filename=None):
        self.machines = []
        if filename:
            self.read_csv(filename=filename)

    def is_ip_valid(self, ip: str) -> bool:
        '判断IP是否合法'
        items = re.findall(r'\d+', ip)  # '172.25.17.8' --> ['172', '25', '17', '8']
        # 合法的IP由4段数字组成,如果不是,则返回False
        if len(items) != 4: return False
        # 扩展知识:
        #   1. all(list), 列表里的每一个元素全部为True的时候,返回True
        #   2. any(list), 列表里的每一个元素全部为False的时候,返回False
        #   3. 列表生成式:
        return all([0 <= int(item) <= 255 for item in items])

    def append(self, hostname: str, IP: str, CPU: int = 2, memeory: int = 4,
               diskCategory: str = '普通云盘', diskSize: int = 40, status: str = 'Running', **kwargs):
        """添加云主机"""
        if not self.is_ip_valid(IP):
            raise Exception(f'云主机ip={IP}不合法')
        m = Machine(hostname, IP, CPU, memeory, diskCategory, diskSize, status)
        self.machines.append(m)

    def find_machine(self, IP) -> int:
        """根据ip去寻找指定云主机的索引,如果没找到抛出异常,如果找到则返回索引"""
        index = 0
        for machine in self.machines:
            if machine.IP == IP:
                return index
            index += 1
        else:
            raise Exception(f'云主机{IP}不存在')

    def update(self, IP, key=None, value=None):
        """更新云主机"""
        index = self.find_machine(IP)
        m = self.machines[index]
        if hasattr(m, key):
            setattr(m, key, value)
        else:
            raise Exception(f'Machine类不存在{key}属性')

    def delete(self, IP):
        """删除云主机"""
        index = self.find_machine(IP)
        self.machines.pop(index)

    def reterive(self, IP):
        """查看指定云主机信息"""
        index = self.find_machine(IP)
        return self.machines[index].to_dict()

    def list_all(self):
        """列出所有的云主机"""
        print(self.machines)

    def prettytable_list_all(self):
        """使用美化的表格去展示"""
        # 实例化表格对象并指定表头
        table = pt.PrettyTable(field_names=["主机名", "IP地址", "CPU", "内存(单位:G)", "磁盘类型", "磁盘大小(单位:G)", "运行状态"])
        # 遍历所有云主机,将云主机信息添加到table对象中。
        for machine in self.machines:
            table.add_row([machine.hostname, machine.IP, machine.CPU,
                           machine.memory, machine.diskCategory, machine.diskSize, machine.status])
        # 打印表格
        print(table)

    def to_csv(self, filename='machines.csv'):
        """
        将云主机信息存储到csv文件中
        :return:
        """
        # machines数据结构是列表里面嵌套字典, [{'hostname':'xxx', 'IP':'xxx', xxx}, {'hostname':'xxx', 'IP':'xxx', xxx}]
        machines = []
        for m in self.machines:
            # m.to_dict()是Machine的一个方法,用于将machine对象转成字典格式
            machines.append(m.to_dict())

        # 将数据转成dataframe对象
        df = pd.DataFrame(machines)
        df.to_csv(filename)
        print(f'存储到文件{filename}成功')

    def read_csv(self, filename='machines.csv'):
        """
        加载文件中的云主机信息到内存中self.machines
        :param filename:
        :return:
        """
        df = pd.read_csv(filename)
        machines = df.T.to_dict().values()  # {0: {'name': 'hello1', 'age': 18, 'score': 100}, 1: {'name': 'hello2', 'age': 19, 'score': 99}}
        # **machine做解包的操作,将获取machine的值依次传给Machine的构造方法。
        self.machines = [Machine(**machine) for machine in machines]
        print('加载数据库的信息成功....')


def main():
    menu = """
                                云主机管理系统
        1). 添加云主机
        2). 更新云主机
        3). 查看云主机
        4). 删除云主机
        5). 持久化存储云主机
        6). 退出
    请输入你的选择:"""
    manager = MachineManager(filename=FILENAME)
    while True:
        """
        
        hostname: str, IP: str, CPU: int = 2, memeory: int = 4,
                 diskCategory: str = '普通云盘', diskSize: int = 40, status: str = 'Running'
        """
        choice = input(menu)
        if choice == '1':
            print('添加云主机'.center(50, '*'))
            hostname = input('hostname:')
            IP = input('IP:')
            CPU = int(input('CPU:'))
            memeory = int(input('memeory(默认单位 G):'))
            diskCategory = input('diskCategory(可选:普通云盘,高效云盘):')
            diskSize = int(input('diskSize(默认单位 G):'))
            status = input('status(可选:Running,Stopped):')
            # 异常捕获机制
            try:
                manager.append(hostname=hostname, IP=IP, CPU=CPU, memeory=memeory,
                               diskCategory=diskCategory, diskSize=diskSize, status=status)
            except Exception as e:
                print(f'添加云主机{IP}失败,原因:{str(e)}')
            else:
                print(f'添加云主机{IP}成功')
        elif choice == '2':
            print('更新云主机'.center(50, '*'))
            IP = input('更新的云主机IP:')
            try:
                manager.find_machine(IP)
                key = input('更新的属性名:')
                value = input('更新的属性值:')
                manager.update(IP, key, value)
            except Exception as e:
                print(f'更新云主机{IP}失败,原因:{str(e)}')
            else:
                print(f'更新云主机{IP}成功')
        elif choice == '3':
            print('查看云主机'.center(50, '*'))
            manager.prettytable_list_all()
        elif choice == '4':
            print('删除云主机'.center(50, '*'))
            IP = input('更新的云主机IP:')
            try:
                manager.delete(IP)
            except Exception as e:
                print(f'删除云主机{IP}失败,原因:{str(e)}')
            else:
                print(f'删除云主机{IP}成功')

        elif choice == '5':
            print('持久化存储云主机'.center(50, '*'))
            manager.to_csv(FILENAME)
        elif choice == '6':
            print()
            print('退出云主机管理系统'.center(50, '*'))
            exit(0)
        else:
            print('请输入正确的选择')


if __name__ == '__main__':
    main()

1. 云主机类的测试

 m1 = Machine(hostname='westos1', IP='172.25.254.1')
 print(m1.start())
 print(m1.stop())
 print(m1.reboot())

2.云主机管理的测试

  manager = MachineManager(filename='data/machines.csv')
    manager.prettytable_list_all()
    manager.to_csv(filename='data/machines.csv')

3.追加操作完成

for i in [1, 2, 3, 6, 7]:  # i=0, 1, 2, 3, 4
        manager.append(hostname=f'westos{i}', IP=f'172.25.254.{i}')

4.查看所有的云主机信息

manager.list_all()
manager.prettytable_list_all()
manager.to_csv('data/machines.csv')

5.读取csv文件的内容

 manager.read_csv('data/machines.csv')
 manager.prettytable_list_all()

你可能感兴趣的:(python,python,开发语言)