python练习-购物车

需求

  1. 根据用户输入输出对应的backend下的server信息
  2. 可添加backend 和sever信息
  3. 可修改backend 和sever信息
  4. 可删除backend 和sever信息
  5. 操作配置文件前进行备份
  6. 加server信息时,如果ip已经存在则修改;如果backend不存在则创建;若信息与已有信息重复则不操作

代码实现

#!/usr/bin/env python
# -*- conding:utf-8 -*-
# Author : QiuMeng

import os


def search(backend_name):
    '''
    根据当前的backend_name,获取record的server信息列表
    :param backend_name: 要查询的backend名称(str)
    :return: 返回record的server信息列表(list)
    '''
    server_info = []  # 初始化server信息列表
    with open("haproxy.conf","r",encoding="utf-8") as f:
        read_flag = False  # 读取添加到list的标记,为false则跳过去,为True的时候添加到list中
        for line in f:
            if line.strip().startswith("backend") and line.strip() == "backend " + backend_name:
                # 以backend开头的行且行内容为"backend www.oldboy.com的行"
                read_flag = True # 告诉程序下一行要开始读取添加了
                continue
            if line.strip().startswith("backend") and line.strip() != "backend " + backend_name:
                # 以backend开头的行且行内容不为"backend www.oldboy.com的行"
                read_flag = False # 不读取标记生效
                continue
            if read_flag and line.strip(): # 如果读取标记生效切该行不为空
                server_info.append(line.strip())  #该行去除空格以及换行符后添加到list中作为list的一个元素
                continue
    return server_info



def add_backend(backend_name,server_name):
    '''
    根据用户输入的backend_name,向其中添加record的server条目(ip地址,权重,最大连接数)
    :param backend_name: 要添加的backend名称(str)
    :param server_name:eg"server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000"(str)
    :return: None
    '''
    os.system("rsync haproxy.conf haproxy.conf.copy")  # backup
    backend_info = "backend " + backend_name
    record_list = search(backend_name)
    if not record_list:  # 为空,直接将新增的添加到文件的最后
        record_list.append(server_name)
        with open("haproxy.conf", "r", encoding="utf-8") as f, open("haproxy.conf.back", 'w',
                                                                    encoding='utf-8') as f_back:
            for local_line in f:
                f_back.write(local_line)
            f_back.write(backend_info + '\n') # 直接将新增的添加到文件的最后
            for server_item in record_list:
                f_back.write(" " * 8 + server_item + '\n')
    else:  # 不为空,将新的server_name信息添加到原来的列表的后面,以便于后续的使用
        record_list.insert(0, backend_info)
        if server_name not in record_list:  # 如果已经存在直接不添加
            record_list.append(server_name)
        with open("haproxy.conf", "r", encoding="utf-8") as f, open("haproxy.conf.back", 'w',
                                                                    encoding='utf-8') as f_back:
            add_flag = False  # 添加红绿灯
            has_writed = False  # 是否已经写了标记
            for local_line in f:
                if local_line.strip() == backend_info:  # 循环时遇到当前需要添加的backend那一行
                    add_flag = True  # 标记添加标记为=绿灯
                    continue  # 跳到下一行
                if local_line.strip().startswith("backend") and add_flag:  # 循环时遇到后面一个backend
                    add_flag = False  # 标记添加标记为红灯
                if add_flag == False:  # 添加标记为红灯,直接写到新文件
                    f_back.write(local_line)
                else:  # 绿灯
                    if has_writed == False:  #并且没有写过
                        for server_item in record_list:
                            if server_item == backend_info:
                                f_back.write(backend_info + '\n')  #先写backend那一行
                            else:
                                f_back.write(" " * 8 + server_item + '\n')  #写server信息

                    has_writed = True  # 防止多写多次,如果修改的那个backend的最后面有几行空行,那就会再写几遍这个backend

    os.system("rsync haproxy.conf.back haproxy.conf")  #覆盖源文件


def del_backend(backend_name,server_name):
    '''
    根据backend_name,server_name删除一条server条目
    :param backend_name: 要添加的backend名称(str)
    :param server_name:eg"server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000"(str)
    :return:None
    '''
    os.system("rsync haproxy.conf haproxy.conf.copy")  # backup
    backend_info = "backend " + backend_name
    record_list = search(backend_name)   # 获取当前backend的server列表
    record_list.insert(0, backend_info)  # 插入backend信息,便于后面取用
    if server_name in record_list:   # 如果用户输入在list中则执行删除,不存在不做任何动作
        record_list.remove(server_name)  #删除server
        if len(record_list) != 1:  #如果不等于1则将会删除server信息,说明改backend下还有其他server信息
            with open("haproxy.conf", "r", encoding="utf-8") as f, open("haproxy.conf.back", 'w',
                                                                        encoding='utf-8') as f_back:
                del_flag = False  # 添加红绿灯
                has_deleted = False  # 是否已经删除标记
                for local_line in f:
                    if local_line.strip() == backend_info:  # 循环时遇到当前需要添加的backend那一行
                        del_flag = True  # 标记添加标记为=绿灯
                        continue  # 跳到下一行
                        # f_back.write(local_line)
                    if local_line.strip().startswith("backend") and del_flag:  # 循环时遇到后面一个backend
                        del_flag = False  # 标记添加标记为红灯
                    if del_flag == False:   # 删除标记为红灯,直接写入新文件
                        f_back.write(local_line)
                    else:   #为绿灯
                        if has_deleted == False:  #是否将删除的添加过
                            for server_item in record_list:
                                if server_item == backend_info:  #写backend
                                    f_back.write(backend_info + '\n')
                                else:  #写server
                                    f_back.write(" " * 8 + server_item + '\n')
                        has_deleted = True
        elif len(record_list) == 1:  #如果等于1,则说明这个nackend也应该删除
            print("这个backend下只有一条记录,删除该条记录后这个backend也会清除")
            with open("haproxy.conf", "r", encoding="utf-8") as f, open("haproxy.conf.back", 'w',
                                                                        encoding='utf-8') as f_back:
                del_flag = False  # 添加红绿灯
                for local_line in f:
                    if local_line.strip() == backend_info:
                        del_flag = True# 标记添加标记为绿灯
                        continue  #直接下一行
                    if local_line.strip().startswith("backend") and del_flag:
                        del_flag = False
                    if del_flag == False:
                        f_back.write(local_line)
    os.system("rsync haproxy.conf.back haproxy.conf")  # 覆盖源文件


def update_backend(backend_name, record_list):
    '''
    根据backend_name,server_name修改server_name信息,可以修改weight,maxconn
    :param backend_name:
    :return:None
    '''
    os.system("rsync haproxy.conf haproxy.conf.copy")  # backup
    backend_info = "backend " + backend_name
    record_list.insert(0, backend_info)  # 插入backend信息,便于后面取用
    with open("haproxy.conf", "r", encoding="utf-8") as f, open("haproxy.conf.back", 'w',
                                                                encoding='utf-8') as f_back:
        update_flag = False  # 添加红绿灯
        has_deleted = False  # 是否已经更新标记
        for local_line in f:
            if local_line.strip() == backend_info:  # 循环时遇到当前需要添加的backend那一行
                update_flag = True  # 标记添加标记为=绿灯
                continue  # 跳到下一行
                # f_back.write(local_line)
            if local_line.strip().startswith("backend") and update_flag:  # 循环时遇到后面一个backend
                update_flag = False  # 标记添加标记为红灯
            if update_flag == False:  # 更新标记为红灯,直接写入新文件
                f_back.write(local_line)
            else:  # 为绿灯
                if has_deleted == False:  # 是否将删除的添加过
                    for server_item in record_list:
                        if server_item == backend_info:  # 写backend
                            f_back.write(backend_info + '\n')
                        else:  # 写server
                            f_back.write(" " * 8 + server_item + '\n')
                has_deleted = True
    os.system("rsync haproxy.conf.back haproxy.conf")  # 覆盖源文件
    exit()


def update(backend_name):
    '''
    :param backend_name: 当前修改的backend_name
    :return: None
    '''
    record_list = search(backend_name)  # 获取当前backend下的server信息
    print("当前该backend下的server信息:".center(50, '-'))
    for i in record_list:
        print(i)
    server_name_ip = input("(只限于修改weight,maxconn)请输入需要修改的server信息的ip地址:") # 用户输入server的ip地址
    for item in record_list:
        server_info = item.split()
        if server_name_ip in server_info: # 用户输入的ip在server条目中
            command = input("确认需要修改的对象[w=weight,m=maxconn]:")  # 确认修改独对象
            if command == "w" or command == 'weight':
                weight_update = input("当前正在修改\033[31;1m{backend_name}\033[0m下"
                                      "\033[31;1m{server_name}\033[0m的\033[31;1mweight\033[0m,"
                                      "请输入修改的值:".format(backend_name=backend_name, server_name=server_info))
                if weight_update.isdigit():  #输入判断
                    server_info[server_info.index("weight") + 1] = weight_update
                    server_info = ' '.join(server_info)  #转化为字符串
                    record_list[record_list.index(item)] = server_info #修改record_list
                    # TODO
                    update_backend(backend_name, record_list)  #调用update_backend函数修改,使用新的record_list
                else:
                    print("你狗日的乱搞!")
            elif command == 'm' or command == 'maxconn':
                maxconn_update = input("当前正在修改\033[31;1m{backend_name}\033[0m下"
                                       "\033[31;1m{server_name}\033[0m的\033[31;1mmaxconn\033[0m,"
                                       "请输入修改的值:".format(backend_name=backend_name, server_name=server_info))
                if maxconn_update.isdigit():  # 输入判断
                    server_info[server_info.index("maxconn") + 1] = maxconn_update  # 列表修改
                    server_info = ' '.join(server_info)  # 转化为字符串
                    record_list[record_list.index(item)] = server_info # 修改record_list
                    # TODO
                    update_backend(backend_name, record_list)  # 调用update_backend函数修改,使用新的record_list
                else:
                    print("你狗日的乱搞!")
            else:
                print("你狗日的乱搞!")
        else:
            print("\033[31;1m输入的ip在当前backend中未能查询到!\033[0m")  #输入ip没有查询到


if __name__ == '__main__':
    while True:
        user_choice = input("欢迎进入haproxy配置文件管理中心,选择动作[q=退出,d=删除,a=添加,s=获取,u=修改]:")
        if user_choice == 'd':
            backend_name = input("请输入需要删除的backend名称:")
            this_backend_server_list = search(backend_name)  # 获取原有server列表
            print("当前该backend下的server信息:".center(50,'-'))
            for i in this_backend_server_list:
                print(i)
            user_choice_server = input("请输入想要删除的一条完整的server信息(原文件会备份为\"haproxy.conf.copy\"]):")
            if user_choice_server in this_backend_server_list:  # 在原有列表中则可以删除
                del_backend(backend_name,user_choice_server)
            else:
                print("输入有误,请重新进入")
            print("删除成功")
            break
        if user_choice == 'a':  # 收入为a,为添加一条server记录
            backend_name = input("请输入需要添加的backend名称:")  # 获取backend信息
            this_backend_server_list = search(backend_name)  # 获取原有server列表
            print("当前该backend下的server信息:".center(50,'-'))   # 向用户展示原有的
            for i in this_backend_server_list:
                print(i)
            user_choice_server = input("请输入想要添加的一条完整的server信息(原文件会备份为\"haproxy.conf.copy\"]):")
            if user_choice_server :   #输入不为空
                add_backend(backend_name,user_choice_server)  # 调用add_backend函数添加
            else:
                # TODO 用户输入server信息的格式正确性判断
                pass
            print("添加成功")
            break
        if user_choice == 's':
            backend_name = input("请输入需要搜索查看的backend名称:")
            this_backend_server_list = search(backend_name)  # 获取原有server列表
            print("当前该backend下的server信息:".center(50,'-'))
            for i in this_backend_server_list:
                print(i)
            break
        if user_choice == 'u':
            backend_name = input("请输入需要更新的backend名称:")
            update(backend_name)   # 调用update函数修改
            print("修改成功")
        if user_choice == 'q':
            break
        else:
            print("输入有误,请重试")
            continue


posted @ 2017-03-06 22:43  我的胡子有点扎  阅读(201)  评论(0)    收藏  举报