haproxy增删改查功能实现以及代码优化

1.haproxy增删改查功能
总结要点:
1.字典具有无序性,不可重复性

2.利用字典的key值获取value值进而用作为函数,并将输入值作为参数传给函数的方法使用
3.python in/not in ---- if not/if
 区分几个容易出错的地方:
in 成员运算符 - 如果字符串中包含给定的字符返回 True
>>>"H" in a True
not in 成员运算符 - 如果字符串中不包含给定的字符返回 True
>>>"M" not in a True

代码中经常会有变量是否为None的判断,有三种主要的写法:

第一种是`if x is None`;

第二种是 `if not x:`;

第三种是`if not x is None`(这句这样理解更清晰`if not (x is None)`) 。

if x is not None`是最好的写法,清晰,不会出现错误,以后坚持使用这种写法。

使用if not x这种写法的前提是:必须清楚x等于None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()时对你的判断没有影响才行

      在python中 None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()都相当于False 

因此在使用列表的时候,如果你想区分x==[]和x==None两种情况的话, 此时`if not x:`将会出现问题:

复制代码
>>> x = []  
>>> y = None  
>>>   
>>> x is None  
False  
>>> y is None  
True  
复制代码

也许你是想判断x是否为None,但是却把`x==[]`的情况也判断进来了,此种情况下将无法区分。

对于习惯于使用if not x这种写法的pythoner,必须清楚x等于None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()时对你的判断没有影响才行。 

      而对于`if x is not None`和`if not x is None`写法,很明显前者更清晰,而后者有可能使读者误解为`if (not x) is None`,因此推荐前者,同时这也是谷歌推荐的风格

# Author rendelei

#_*_coding:utf-8_*_
import  os

import datetime


def fetch(data):
    # backend www.oldboy.org
    # server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
    backend_data ="backend %s" %data
    record_list = []
    with open("D:\python_project\storage\cap1\ha_config.txt",'r') as f:
        tag = False  #设置标签
        for line in f:
            if line.strip() == backend_data:  #判断如果匹配到backend,则就标签设置为True
                tag =True
                continue
            if tag and line.startswith("backend"):  #判断如果匹配到下一个以backend开始的字符串,则退出for循环。
                break                         #由于tag为True,因此需要将判断匹配下一个backend放在添加record列表前面
            if tag and  line:                 #将backend匹配的下面的行添加到record_list的列表中
                record_list.append(line.strip())  #line.strip()去掉line结果的空行
        for line in record_list:
            print(line)
        print (record_list)
        return record_list                    #将record_list列表的值返回给函数fetch(data)


def add(data):
    #格式:dict {"backend":"www.oldboy5.org","record":{"server":"10.10.10.10","server":"10.10.10.10","weight":"20","maxconn":"300"}}
    value = data['backend']    # 取出key为backend的字典的value值
    record_list = fetch(value) #value值作为查询函数的参数传给fetch(),并将函数的返回值赋值给record_list
    #将backend下面行的内容通过字典的value值匹配,并赋值给current_record
    current_record = "server %s %s weight %s maxconn %s" %(data['record']['server'],\
                                                           data['record']['server'],\
                                                           data['record']['weight'],\
                                                           data['record']['maxconn'])
    backend_data = "backend %s" %value

    if not record_list:
        record_list.append(backend_data)
        record_list.append(current_record)
        with open ("D:\python_project\storage\cap1\ha_config.txt",'r') as r_file, \
                open("D:\python_project\storage\cap1\ha_config_new.txt", 'w') as w_file:
            for r_line in r_file:                             #将源文件写入新文件
                w_file.write(r_line)
            for new_line in record_list:
                if new_line.startswith('backend'):
                    w_file.write(new_line+'\n')
                else:
                    w_file.write("%s%s\n" % (' '*8,new_line))
    else:
        #即record_list不为空
        # 在record_list中添加backend 信息,如果添加的backend信息已经存在,
        record_list.insert(0,backend_data)
        #将要添加的sever信息记录加到record_list中
        if current_record not in record_list:  #???如果添加的新的信息在record_list中,输出已经存在该信息,else怎么会出现问题,但是测试没问题?(格式问题,已解决)
            record_list.append(current_record)
            with open("D:\python_project\storage\cap1\ha_config.txt", 'r') as r_file, \
                    open("D:\python_project\storage\cap1\ha_config_new.txt", 'w') as w_file:
                tag = False
                # 由于在else模块中tag为True在读相应的server信息中,会每读一行,则写一次record_list中的信息
                # 因此需要判断在读到新的backend信息之前只需写一次record_list信息即可
                has_write = False
                for r_line in r_file:
                    if r_line.strip() == backend_data:
                        tag = True
                        continue
                    if tag and r_line.startswith('backend'):
                        tag = False
                    if not tag:
                        w_file.write(r_line)
                    else:
                        if not has_write:
                            for new_line in record_list:
                                if new_line.startswith('backend'):
                                    w_file.write(new_line + '\n')
                                else:
                                    w_file.write("%s%s\n" % (' ' * 8, new_line))
                            has_write = True



            # 更改文件名
            os.rename("D:\python_project\storage\cap1\ha_config.txt",
                              "D:\python_project\storage\cap1\ha_config_bak.txt")
            os.rename("D:\python_project\storage\cap1\ha_config_new.txt",
                              "D:\python_project\storage\cap1\ha_config.txt")
            os.remove("D:\python_project\storage\cap1\ha_config_bak.txt")
        else:
            print("This record is already exist!")


def remove(data):
    value = data['backend']
    record_list = fetch(value)
    current_record = "server %s %s weight %s maxconn %s" % (data['record']['server'], \
                                                            data['record']['server'], \
                                                            data['record']['weight'], \
                                                            data['record']['maxconn'])
    backend_data = "backend %s" % value
    if not record_list or current_record not in record_list:
        print("\033[41;1mThere is no record of this!\033[0m")
        return
    else:
        record_list.insert(0,backend_data)
        record_list.remove(current_record)
        with open("D:\python_project\storage\cap1\ha_config.txt", 'r') as r_file, \
                open("D:\python_project\storage\cap1\ha_config_new.txt", 'w') as w_file:
            tag = False
            has_write = False
            for r_line in r_file:
                if r_line.strip() == backend_data:
                    tag =True
                    continue
                if tag and r_line.startswith('backend'):
                    tag = False
                if not tag:
                    w_file.write(r_line)
                else:
                    if not has_write:
                        for new_line in record_list:
                            if new_line.startswith('backend'):
                                w_file.write(new_line + '\n')
                            else:
                                w_file.write("%s%s\n" % (' ' * 8, new_line))
                        has_write = True
    os.rename("D:\python_project\storage\cap1\ha_config.txt", "D:\python_project\storage\cap1\ha_config_bak.txt")
    os.rename("D:\python_project\storage\cap1\ha_config_new.txt", "D:\python_project\storage\cap1\ha_config.txt")
    os.remove("D:\python_project\storage\cap1\ha_config_bak.txt")
def change(data):
# 格式:[{"backend":"www.oldboy5.org","record":{"server":"10.10.10.10","weight":"20","maxconn":"300"}},
# {"backend":"www.oldboy5.org","record":{"server":"18.18.18.18","weight":"200","maxconn":"3000"}}]
    backend = data[0]['backend']
    record_list = fetch(backend)
    old_record = "server %s %s weight %s maxconn %s" % (data[0]['record']['server'], \
                                                            data[0]['record']['server'], \
                                                            data[0]['record']['weight'], \
                                                            data[0]['record']['maxconn'])
    new_record = "server %s %s weight %s maxconn %s" % (data[1]['record']['server'], \
                                                            data[1]['record']['server'], \
                                                            data[1]['record']['weight'], \
                                                            data[1]['record']['maxconn'])
    backend_data = "backend %s" %backend
    if not record_list or old_record not in record_list:  #为空或者要修改的内容信息与record_list不一致
        print("\033[41;1mThere is no this record!\033[0m")
        return
    else:
        record_list.insert(0,backend_data)
        index= record_list.index(old_record)
        record_list[index]= new_record
        with open("D:\python_project\storage\cap1\ha_config.txt", 'r') as r_file, \
                open("D:\python_project\storage\cap1\ha_config_new.txt", 'w') as w_file:
            tag = False
            has_write = False
            for r_line in r_file:
                if r_line.strip() == backend_data:
                    tag = True
                    continue
                if tag and r_line.startswith('backend'):
                    tag = False
                if not tag:
                    w_file.write(r_line)
                else:
                    if not has_write:
                        for new_line in record_list:
                            if new_line.startswith('backend'):
                                w_file.write(new_line + '\n')
                            else:
                                w_file.write("%s%s\n" % (' ' * 8, new_line))
                        has_write = True


    os.rename("D:\python_project\storage\cap1\ha_config.txt", "D:\python_project\storage\cap1\ha_config_bak.txt")
    os.rename("D:\python_project\storage\cap1\ha_config_new.txt", "D:\python_project\storage\cap1\ha_config.txt")
    os.remove("D:\python_project\storage\cap1\ha_config_bak.txt")

def backup(choice):
    with open("D:\python_project\storage\cap1\ha_config.txt", 'r') as r_file, \
            open("D:\python_project\storage\cap1\ha_config_copy_%s.txt" \
                         % datetime.datetime.now().strftime("%Y_%m_%d"), 'w') as w_file:
        for r_line in r_file:
            w_file.write(r_line)
    print("you backup the file successful!")
if __name__ =='__main__':
    mgs='''
    what woul you like to do with this HAproxy file?
    1:fetch
    2:add
    3:delete
    4:change
    5:backup
    6:exit
    '''
    menu_dict={
     '1':fetch,
     '2':add,
     '3':remove,
     '4':change,
     '5':backup,
     '6':exit
    }
    while True:
        print(mgs)   #先输出可选择功能项
        choice = input("select>>>:").strip()
        #判断input的输入,如果是不输入或者输入不为 menu_dict中的key值,则继续循环输入
        if len(choice)== 0 or choice not in menu_dict:continue
        if choice == '5':
            backup(choice)
            continue
        if choice == '6':break
        data = input("data>>>:").strip()
        #判断input的输入,如果不是1,即add or remove ,由于输入格式为字典,则需要进行字典转化为字符串
        if choice is not '1':
            data = eval(data)
        #利用字典的key值获取value值进而用作为函数,并将输入值作为参数传给函数
        menu_dict[choice](data)
View Code

优化代码:

# Author rendelei


#_*_coding:utf-8_*_
import  os
import datetime
def file_handle(filename,backend_data,record_list=None,type='fetch'):
    if type =="fetch":
        # backend www.oldboy.org
        # server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
        r_list = []
        with open(filename, 'r') as f:
            tag = False  # 设置标签
            for line in f:
                if line.strip() == backend_data:  # 判断如果匹配到backend,则就标签设置为True
                    tag = True
                    continue
                if tag and line.startswith("backend"):  # 判断如果匹配到下一个以backend开始的字符串,则退出for循环。
                    break  # 由于tag为True,因此需要将判断匹配下一个backend放在添加record列表前面
                if tag and line:  # 将backend匹配的下面的行添加到record_list的列表中
                    r_list.append(line.strip())  # line.strip()去掉line结果的空行
            for line in r_list:
                print(line)
            return r_list  # 将record_list列表的值返回给函数fetch(data)
    elif type =="append":
        new_filename = filename+"_new"
        bak_filename = filename+"_bak"
        with open("filename", 'r') as r_file, \
                open("filename1", 'w') as w_file:
            for r_line in r_file:  # 将源文件写入新文件
                w_file.write(r_line)
            for new_line in record_list:
                if new_line.startswith('backend'):
                    w_file.write(new_line + '\n')
                else:
                    w_file.write("%s%s\n" % (' ' * 8, new_line))
        # 更改文件名
        os.rename(filename,bak_filename)
        os.rename(new_filename,filename)
        os.remove(bak_filename)
    elif type =="change":
        new_filename = filename + "_new"
        bak_filename = filename + "_bak"
        with open(filename, 'r') as r_file, \
                open(new_filename, 'w') as w_file:
            tag = False
            # 由于在else模块中tag为True在读相应的server信息中,会每读一行,则写一次record_list中的信息
            # 因此需要判断在读到新的backend信息之前只需写一次record_list信息即可
            has_write = False
            for r_line in r_file:
                if r_line.strip() == backend_data:
                    tag = True
                    continue
                if tag and r_line.startswith('backend'):
                    tag = False
                if not tag:
                    w_file.write(r_line)
                else:
                    if not has_write:
                        for new_line in record_list:
                            if new_line.startswith('backend'):
                                w_file.write(new_line + '\n')
                            else:
                                w_file.write("%s%s\n" % (' ' * 8, new_line))
                        has_write = True

        # 更改文件名
        os.rename(filename, bak_filename)
        os.rename(new_filename, filename)
        os.remove(bak_filename)

def fetch(data):
    backend_data = "backend %s" % data
    return file_handle("D:\python_project\storage\cap1\ha_config",backend_data,type='fetch')


def add(data):
    #格式:dict {"backend":"www.oldboy5.org","record":{"server":"10.10.10.10","server":"10.10.10.10","weight":"20","maxconn":"300"}}
    value = data['backend']    # 取出key为backend的字典的value值
    record_list = fetch(value) #value值作为查询函数的参数传给fetch(),并将函数的返回值赋值给record_list
    #将backend下面行的内容通过字典的value值匹配,并赋值给current_record
    current_record = "server %s %s weight %s maxconn %s" %(data['record']['server'],\
                                                           data['record']['server'],\
                                                           data['record']['weight'],\
                                                           data['record']['maxconn'])
    backend_data = "backend %s" %value
    if not record_list:
        record_list.append(backend_data)
        record_list.append(current_record)
        file_handle("D:\python_project\storage\cap1\ha_config",backend_data,record_list,type="append")
    else:
        #即record_list不为空
        # 在record_list中添加backend 信息,如果添加的backend信息已经存在,
        record_list.insert(0,backend_data)
        #将要添加的sever信息记录加到record_list中
        if current_record not in record_list:  #???如果添加的新的信息在record_list中,输出已经存在该信息,else怎么会出现问题,但是测试没问题?(格式问题,已解决)
            record_list.append(current_record)
            file_handle("D:\python_project\storage\cap1\ha_config", backend_data, record_list, type="change")
        else:
            print("\033[41;1mThis record is already exist!\033[0m")


def remove(data):
    value = data['backend']
    record_list = fetch(value)
    current_record = "server %s %s weight %s maxconn %s" % (data['record']['server'], \
                                                            data['record']['server'], \
                                                            data['record']['weight'], \
                                                            data['record']['maxconn'])
    backend_data = "backend %s" % value
    if not record_list or current_record not in record_list:
        print("\033[41;1mThere is no such record !\033[0m")
        return
    else:
        record_list.insert(0,backend_data)
        record_list.remove(current_record)
        file_handle("D:\python_project\storage\cap1\ha_config", backend_data, record_list, type="change")
def change(data):
# 格式:[{"backend":"www.oldboy5.org","record":{"server":"10.10.10.10","weight":"20","maxconn":"300"}},
# {"backend":"www.oldboy5.org","record":{"server":"18.18.18.18","weight":"200","maxconn":"3000"}}]
    backend = data[0]['backend']
    record_list = fetch(backend)
    old_record = "server %s %s weight %s maxconn %s" % (data[0]['record']['server'], \
                                                            data[0]['record']['server'], \
                                                            data[0]['record']['weight'], \
                                                            data[0]['record']['maxconn'])
    new_record = "server %s %s weight %s maxconn %s" % (data[1]['record']['server'], \
                                                            data[1]['record']['server'], \
                                                            data[1]['record']['weight'], \
                                                            data[1]['record']['maxconn'])
    backend_data = "backend %s" %backend
    if not record_list or old_record not in record_list:  #为空或者要修改的内容信息与record_list不一致
        print("\033[41;1mThere is no this record!\033[0m")
        return
    else:
        record_list.insert(0,backend_data)
        index= record_list.index(old_record)
        record_list[index]= new_record
        file_handle("D:\python_project\storage\cap1\ha_config", backend_data, record_list, type="change")

def backup(choice):
    with open("D:\python_project\storage\cap1\ha_config", 'r') as r_file, \
            open("D:\python_project\storage\cap1\ha_config_copy_%s.txt" \
                         % datetime.datetime.now().strftime("%Y_%m_%d"), 'w') as w_file:
        for r_line in r_file:
            w_file.write(r_line)
    print("you backup the file successful!")
if __name__ =='__main__':
    mgs='''
    what woul you like to do with this HAproxy file?
    1:fetch
    2:add
    3:delete
    4:change
    5:backup
    6:exit
    '''
    menu_dict={
     '1':fetch,
     '2':add,
     '3':remove,
     '4':change,
     '5':backup,
     '6':exit
    }
    while True:
        print(mgs)   #先输出可选择功能项
        choice = input("select>>>:").strip()
        #判断input的输入,如果是不输入或者输入不为 menu_dict中的key值,则继续循环输入
        if len(choice)== 0 or choice not in menu_dict:continue
        if choice == '5':
            backup(choice)
            continue
        if choice == '6':break
        data = input("data>>>:").strip()
        #判断input的输入,如果不是1,即add or remove ,由于输入格式为字典,则需要进行字典转化为字符串
        if choice is not '1':
            data = eval(data)
        #利用字典的key值获取value值进而用作为函数,并将输入值作为参数传给函数
        menu_dict[choice](data)
View Code

 

posted @ 2017-04-09 12:53  伊川草  阅读(248)  评论(0)    收藏  举报