这个作业是包含了循环,函数,文件修改,列表,字典等等的知识点
首先需要改的文件是Haproxy的配置文件
haproxy
global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 info defaults log global mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option dontlognull listen stats :8888 stats enable stats uri /admin stats auth admin:1234 frontend oldboy.org bind 0.0.0.0:80 option httplog option httpclose option forwardfor log global acl www hdr_reg(host) -i www.oldboy.org use_backend www.oldboy.org if www backend www.oldboy.org server 100.1.7.10 100.1.7.10 weight 20 maxconn 3000 backend www.baidu.com server 100.1.7.11 100.1.7.11 weight 20 maxconn 3000
这个是一个参考的代码
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author: Even 4 5 6 import os,sys 7 8 9 def numif(number_input): # 判断输入是否为数字 10 while not number_input.isdigit(): # 输入不是数字就进入循环 11 number_input = input(‘\033[31m 输入%s不是数字,请重新输入!\033[0m‘ % number_input) # 提示重新输入 12 number = number_input 13 return number 14 15 16 def show_list(file): # 查询显示并将文本生成程序需要的字典和列表 17 backend_list = [] 18 backend_all_dict = {} 19 backend_dict = {} 20 server_list = [] 21 with open(file,‘r‘) as f: # 读取haproxy文件 22 for line in f: 23 24 line = line.strip() 25 if line.startswith(‘backend‘) == True: # 判断是否是backend开头,读取backend信息写到backend_list中 26 backend_name = line.split()[1] 27 backend_list.append(backend_name) # 将文件中backend加到列表中 28 server_list = [] # 清空server_list里的记录,遇到新backend可以输入新的server_list 29 30 elif line.startswith(‘server‘) == True: # 判断是否是server开头,读取server信息写到backend_all_dict中 31 backend_dict[‘name‘] = line.split()[1] # 读取文件中server的name 32 backend_dict[‘IP‘] = line.split()[2] # 读取文件中server的IP 33 backend_dict[‘weight‘] = line.split()[4] # 读取文件中server的weight 34 backend_dict[‘maxconn‘] = line.split()[6] # 读取文件中server的maxconn 35 server_list.append(backend_dict.copy()) # 将backend中的信息加到server_list中,此处需要用copy 36 backend_all_dict[backend_name] = server_list # 将server信息对应backend存到字典中 37 38 return (backend_list,backend_all_dict) # 返回backend和server信息 39 40 41 def backend_show(backend_list): # 展示backend列表内容 42 backend_show_dict = {} 43 print("-------------------------------------------------") 44 print("\t\t\t欢迎来到HAproxy文件配置平台") 45 print("-------------------------------------------------") 46 print("backend列表信息如下:") 47 for k,v in enumerate(backend_list,1): # 逐行读取backend信息并展示 48 print(k, v) 49 backend_show_dict[str(k)] = v 50 return backend_show_dict # 返回backend和对应编号 51 52 53 def server_show(backend_input,backend_all_dict): # 展示backend下server内容 54 server_show_dict = {} 55 server_list = backend_all_dict[backend_input] 56 for k,v in enumerate(server_list,1): # 编号展示server信息 57 print(k,"name:",v[‘name‘],"\tIP:",v[‘IP‘],"\tweight:",v[‘weight‘],"\tmaxconn:",v[‘maxconn‘]) 58 server_show_dict[k] = v 59 return server_show_dict # 返回编号对应的server字典 60 61 62 def action_list(): # 显示操作列表和编号,并返回操作编号 63 print("-------------------------------------------------") 64 print("操作清单如下:") 65 print(‘‘‘ 66 1.查询backend和server信息 67 2.添加backend和server信息 68 3.修改backend和server信息 69 4.删除backend和server信息 70 5.退出 71 ‘‘‘) 72 print("-------------------------------------------------") 73 action_num = numif(input("请输入需要操作的编号:(请输入数字)")) 74 return action_num 75 76 77 def inquiry(inquiry_input): # 定义查询功能 78 while True: 79 if inquiry_input in backend_show_dict: # 编号输入分支 80 backend_input = backend_show_dict[inquiry_input] # 输入编号得到backend 81 print(backend_input, ":") 82 server_show(backend_input, backend_all_dict) # 调用server_show,展示backend下server 83 break 84 85 elif inquiry_input in backend_show_dict.values(): # backend名称输入分支 86 print(inquiry_input, ":") 87 server_show(inquiry_input, backend_all_dict) # 调用server_show,展示backend下server 88 break 89 90 else: # 校验异常输入 91 inquiry_input = input("输入错误,请重新输入:") 92 93 94 def add(add_input,file): # 定义添加功能 95 (backend_list, backend_all_dict) = show_list(file) 96 while True: 97 if add_input in backend_show_dict: #添加原有backend下server 98 add_dict = {} 99 add_dict[‘name‘] = input("请输入需增加server名称:") 100 add_dict[‘IP‘] = input("请输入需增加IP地址:") 101 add_dict[‘weight‘] = input("请输入需增加weight值:") 102 add_dict[‘maxconn‘] = input("请输入需增加maxcoon值:") 103 backend_name_add = backend_list[int(add_input)-1] 104 105 for dict in backend_all_dict[backend_name_add]: # 实现IP已存在,更新weight信息和maxconn信息 106 if add_dict[‘IP‘] in dict.values(): 107 dict[‘weight‘] = add_dict[‘weight‘] 108 dict[‘maxconn‘] = add_dict[‘maxconn‘] 109 break 110 111 else: # IP不存在,就将server增加到backend下 112 backend_all_dict[backend_name_add].append(add_dict) 113 114 backup(file,backend_name_add,backend_all_dict) # 调用backup函数,将新增内容读写到文件中 115 print(‘‘‘name:%s IP:%s weight:%s maxconn:%s已添加成功‘‘‘%( 116 add_dict[‘name‘],add_dict[‘IP‘],add_dict[‘weight‘],add_dict[‘maxconn‘])) # 提示添加成功 117 break 118 119 else: # 添加新backend下的server 120 add_dict = {} 121 add_dict[‘name‘] = input("请输入%s下新增server名称:"%add_input) 122 add_dict[‘IP‘] = input("请输入%s下新增IP地址:"%add_input) 123 add_dict[‘weight‘] = input("请输入%s下新增weight值:"%add_input) 124 add_dict[‘maxconn‘] = input("请输入%s下新增maxcoon值:"%add_input) 125 backend_name_add = add_input 126 backend_all_dict[backend_name_add] = add_dict # 将新增backend和对应server存到字典中 127 128 file_new = "%s_new" % file # 新建一个文件,用来新增数据 129 with open(file, ‘r‘) as f_read, open(file_new, ‘a+‘) as f_write: # 读取file文件,追加backend信息 130 for line in f_read: 131 f_write.write(line) 132 f_write.write("\nbackend %s" % backend_name_add) # 追加backend信息 133 server_line_write = ‘\n\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ # 追加server信息 134 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 135 136 os.system(‘mv %s %s_backup‘ % (file, file)) # 将file文件名改为file_backup 137 os.system(‘mv %s %s‘ % (file_new, file)) # 将file_new文件名改为file,实现备份 138 print("\nbackend %s" % backend_name_add) 139 print(‘‘‘name:%s IP:%s weight:%s maxconn:%s已添加成功‘‘‘ % ( 140 add_dict[‘name‘], add_dict[‘IP‘], add_dict[‘weight‘], add_dict[‘maxconn‘])) # 提示添加成功 141 break 142 143 144 def revise(revise_input): # 定义修改功能 145 revise_dict = {} 146 if revise_input in backend_show_dict: # 判断输入是否存在 147 backend_revise = backend_show_dict[revise_input] # 通过编号获取backend 148 revise_choise = input("是否需要修改该backend名称:%s;确认请按‘y‘,按任意键继续:"%backend_revise) # 确认是否修改backend名,输入y修改,否则继续修改 149 if revise_choise == ‘y‘: 150 backend_revise_new = input("请输入修改后的backend名:") # 修改backend名 151 backend_all_dict[backend_revise_new] = backend_all_dict.pop(backend_revise) # 将旧backend的server对应到修改后的backend上 152 revise_choise_server = input("是否需要继续修改%s下的server:确认请按‘y‘,按任意键继续:"%backend_revise_new) # 询问是否继续修改 153 if revise_choise_server == ‘y‘: # 继续修改server 154 server_revise_dict = server_show(backend_revise_new, backend_all_dict) # 展示server信息 155 server_revise_num = numif(input("请输入需要修改的server编号:")) # 获取需要修改的server编号 156 revise_dict[‘name‘] = input("请输入修改后的name:") 157 revise_dict[‘IP‘] = input("请输入修改后的IP:") 158 revise_dict[‘weight‘] = input("请输入修改后的weight:") 159 revise_dict[‘maxconn‘] = input("请输入修改后的maxconn:") 160 server_revise_dict[int(server_revise_num)] = revise_dict # 通过编号修改server信息 161 server_revise_dict_backup = {} 162 server_revise_dict_backup[backend_revise_new] = server_revise_dict.values() # 将修改的server信息对应到修改后的backend存到字典中 163 backup(file, backend_revise, server_revise_dict_backup,backend_revise_new) # 调用backup函数,操作文件 164 165 else: # 不修改server,只修改了backend 166 backup(file, backend_revise, backend_all_dict,backend_revise_new) 167 else: # 未修改backend名情况时修改server信息 168 server_revise_dict = server_show(backend_revise, backend_all_dict) 169 server_revise_num = numif(input("请输入需要修改的server编号:")) # 获取需修改的server编号 170 revise_dict[‘name‘] = input("请输入修改后的name:") 171 revise_dict[‘IP‘] = input("请输入修改后的IP:") 172 revise_dict[‘weight‘] = input("请输入修改后的weight:") 173 revise_dict[‘maxconn‘] = input("请输入修改后的maxconn:") 174 server_revise_dict[int(server_revise_num)] = revise_dict # 修改的server信息对应到编号中存到字典中 175 server_revise_dict_backup = {} 176 server_revise_dict_backup[backend_revise] = server_revise_dict.values() # 将修改后的server信息对应backend存到字典中 177 backup(file,backend_revise,server_revise_dict_backup) # 调用backup函数,操作文件 178 else: # 输入错误提示重新输入 179 revise_input_return = input("需修改backend不存在,请重新输入:") 180 revise(revise_input_return) 181 182 183 def delete(delete_input): # 定义删除功能 184 if delete_input in backend_show_dict: 185 backend_delete = backend_show_dict[delete_input] 186 delete_choise = input("是否需要删除该backend:%s;确认请按‘y‘,按任意键继续:"%backend_delete) 187 if delete_choise == ‘y‘: # 判断是否删除backend信息 188 del backend_all_dict[backend_delete] # 在backend与server总字典中删除backend 189 backup(file, backend_delete, backend_all_dict) # 调用backup函数,操作文件 190 191 else: # 删除server 192 server_delete_dict = server_show(backend_delete, backend_all_dict) 193 server_delete_num = int(numif(input("请输入需要删除的server编号:"))) # 除判断是否时数字外,还需转换为整数型 194 while True: # 删除backend下的server循环 195 if server_delete_num in server_delete_dict: # 判断输入编号是否存在 196 server_delete_dict.pop(server_delete_num) 197 server_delete_dict_backup = {} 198 server_delete_dict_backup[backend_delete] = server_delete_dict.values() 199 backup(file, backend_delete, server_delete_dict_backup) # 调用backup函数,操作文件 200 break 201 else: 202 server_delete_num = input("输入编号不存在,请重新输入:") # 提示输入错误 203 204 205 def backup(file,backend_name_action,backend_backup_dict,*backend_name_revise): # 定义文档备份与回写功能 206 file_new = "%s_new"%file 207 add_flag = False # 为跳过原backend下server存在 208 with open(file,‘r‘) as f_read , open(file_new,‘w+‘) as f_write: # 同时打开读文件和写文件 209 for line in f_read: # 读取每行信息 210 backend_name = "backend %s" % backend_name_action 211 backend_name_revise = "".join(tuple(backend_name_revise)) # 修改功能会传参,将元组转换为字符串 212 if line.strip() == backend_name: # 读取某行中有参数中的backend 213 if backend_name_action not in backend_backup_dict and backend_name_revise not in backend_backup_dict: # 为了删除backend而存在 214 add_flag = True 215 pass 216 217 elif backend_name_revise in backend_backup_dict: # 判断修改功能中修改后backend存在与字典中 218 line_revise = "backend %s\n" % backend_name_revise 219 f_write.write(line_revise) 220 for add_dict in backend_backup_dict[backend_name_revise]: # 逐行读取修改backend下的server信息 221 server_line_write = ‘\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ 222 f_write.write(server_line_write.format(**add_dict)) # 格式化输出 223 add_flag = True 224 225 else: 226 f_write.write(line) # 将此行写在文件中 227 for add_dict in backend_backup_dict[backend_name_action]: # 读取该backend下所有server信息 228 server_line_write = ‘\t\tserver {name} {IP} weight {weight} maxconn {maxconn}\n‘ 229 f_write.write(server_line_write.format(**add_dict)) 230 add_flag = True 231 232 elif line.strip().startswith("server") == True and add_flag == True: # 为了跳过原backend下的server 233 pass 234 235 else: # 写无用行 236 f_write.write(line) 237 add_flag = False # 写下无用行后可以继续循环 238 239 os.system(‘mv %s %s_backup‘ % (file, file)) 240 os.system(‘mv %s %s‘ % (file_new, file)) 241 242 243 def backend_exit(): #定义退出功能 244 flag_exit = True 245 b_input = input("操作完毕退出请按‘b‘:") 246 while flag_exit: 247 if b_input == ‘b‘: 248 flag_exit = False 249 return flag_exit 250 251 else: 252 return backend_exit() #使用尾递归优化,加上return帮助直接退出,而不需要递归一层层退出 253 254 255 flag = True # 主函数开始 256 while flag: 257 flag_main = True 258 flag_action = True 259 file = ‘haproxy‘ # 文件名赋值 260 (backend_list, backend_all_dict) = show_list(file) # 调用show_list函数获取backend和server信息 261 backend_show_dict = backend_show(backend_list) # 展示backend信息 262 action_num = action_list() # 展示功能项,并输入操作编号 263 while flag_main: 264 if action_num == ‘1‘: 265 inquiry(input("请输入需要查询的backend编号或名称:")) 266 flag_main = backend_exit() 267 break 268 269 if action_num == ‘2‘: 270 add(input("请输入需要添加的现有backend编号或新backend名称:"), file) 271 flag_main = backend_exit() 272 break 273 274 if action_num == ‘3‘: 275 revise(input("请输入需要修改的backend编号或名称:")) 276 flag_main = backend_exit() 277 break 278 279 if action_num == ‘4‘: 280 delete(input("请输入需要删除的backend编号或名称:")) 281 flag_main = backend_exit() 282 break 283 284 if action_num == ‘5‘: 285 sys.exit() 286 287 elif action_num not in range(5): # 当输入不在编号中,提示并重新输入 288 print("\033[31;1m输入错误请重新输入!\033[0m") 289 flag_main = False
参考代码
主要的思想是先办法把需要拿到的数据变成字典或者列表,让后通过增删改查的方式把列表或者字典改成需要的样子,然后再按照格式把字典或者列表写入到另外一个文件中。
然后再把新的文件替换掉现有的文件就可以完成任务了
中间要主要函数的实用,尽量把过程分开化,合理的定义每个功能的函数再调用。(这个是重点)
时间: 2024-11-09 10:41:11