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)
优化代码:
# 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)


浙公网安备 33010602011771号