一.作业需求:

1. 根据用户输入输出对应的backend下的server信息

2. 可添加backend 和sever信息

3. 可修改backend 和sever信息

4. 可删除backend 和sever信息

5. 操作配置文件前进行备份

6 添加server信息时,如果ip已经存在则修改;如果backend不存在则创建;若信息与已有信息重复则不操作

配置文件 参考 http://www.cnblogs.com/alex3714/articles/5717620.html

二.配置文件:

  1. global
  2. log 127.0.0.1 local2
  3. daemon
  4. maxconn 256
  5. log 127.0.0.1 local2 info
  6. defaults
  7. log global
  8. mode http
  9. timeout connect 5000ms
  10. timeout client 50000ms
  11. timeout server 50000ms
  12. option dontlognull
  13.  
  14. listen stats :8888
  15. stats enable
  16. stats uri /admin
  17. stats auth admin:1234
  18.  
  19. frontend oldboy.org
  20. bind 0.0.0.0:80
  21. option httplog
  22. option httpclose
  23. option forwardfor
  24. log global
  25. acl www hdr_reg(host) -i www.oldboy.org
  26. use_backend www.oldboy.org if www
  27.  
  28. backend www.oldboy.org
  29. server 110.1.1.2 110.1.1.2 weight 20 maxconn 2000
  30. server 110.1.1.1 110.1.1.1 weight 30 maxconn 3000
  31.  
  32. backend www.12345.com.cn
  33. server 100.1.7.8 100.1.7.8 weight 10 maxconn 1000
  34.  
  35. backend www.baidu.com
  36. server 100.0.0.1 100.0.0.1 weight 80 maxconn 1000

三.流程图:

四.代码:(python3.6 mac环境)

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

五.效果图:

(1)查询:

in

(2)添加新backend:

(3)添加backend下server:

(4)修改backend:

(5)修改server:

(6)删除server:

(7)删除backend:

python作业:HAproxy配置文件操作(第三周)的更多相关文章

  1. python之haproxy配置文件操作(第三天)

    作业: 对haproxy配置文件进行操作 要求: 对haproxy配置文件中backend下的server实现增删改查的功能 一.这个程序有二个版本 1. python2.7版本见haproxy_py ...

  2. Python作业工资管理系统(第三周)

    作业内容: 实现效果: 从info.txt文件中读取员工及其工资信息,最后将修改或增加的员工工资信息也写入原info.txt文件. 效果演示: 1. 查询员工工资 2. 修改员工工资 3. 增加新员工 ...

  3. 第三周作业HAproxy文件操作

    #coding:utf-8 #Author:Mr Zhi """ HAproxy配置文件操作: 1. 根据用户输入输出对应的backend下的server信息 2. 可添 ...

  4. python对mysql数据库操作的三种不同方式

    首先要说一下,在这个暑期如果没有什么特殊情况,我打算用python尝试写一个考试系统,希望能在下学期的python课程实际使用,并且尽量在此之前把用到的相关技术都以分篇博客的方式分享出来,有想要交流的 ...

  5. s12-day03-work01 python修改haproxy配置文件(初级版本)

    #!/usr/local/env python3 ''' Author:@南非波波 Blog:http://www.cnblogs.com/songqingbo/ E-mail:qingbo.song ...

  6. 作业-haproxy配置文件的增删查(有一个bug不知道咋改)

    # yangqiao #查询 ''' f=open("C:\\aaaaaaaaaaaaa\\haproxy.txt", "r", encoding=" ...

  7. Python作业选课系统(第六周)

    作业需求: 角色:学校.学员.课程.讲师.完成下面的要求 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 ...

  8. python3 haproxy配置文件操作练习

    哈哈 老规矩 先来一个NLP第六条:咳咳! 六,重复旧的做法,只会得到旧的结果   做法有不同,结果才会有不同. 如果,你的事没有结果,改变你的做法.任何新的做法,都比旧的多一份成功的机会. 想明天比 ...

  9. python作业简单FTP(第七周)

    作业需求: 1. 用户登陆 2. 上传/下载文件 3. 不同用户家目录不同 4. 查看当前目录下文件 5. 充分使用面向对象知识 思路分析: 1.用户登陆保存文件对比用户名密码. 2.上传用json序 ...

随机推荐

  1. BZOJ 3235: [Ahoi2013]好方的蛇

    BZOJ 3235: [Ahoi2013]好方的蛇 标签(空格分隔): OI-BZOJ OI-DP OI-容斥原理 Time Limit: 10 Sec Memory Limit: 64 MB Des ...

  2. 关于VMware给系统分区扩容的一点经验

    我的VMware版本是8.0.6 build-1035888,里面安装的是Windows XP SP3 首先,在VM关机状态下使用Hard disk设置中的Utilities下的Expand给整个磁盘 ...

  3. PASCAL VOC数据集分析

    http://blog.csdn.net/zhangjunbob/article/details/52769381

  4. Getting aCC Error :name followed by "::" must be a class or namespace name"

    Getting aCC Error :name followed by "::" must be a class or namespace name" 原始是这样子的: ...

  5. flexslider 图片轮播插件参数

    $(window).load(function() { $('.flexslider').flexslider({ animation: "fade", //String: Sel ...

  6. 激活SQLPrompt7.4及以上版本

    SQLPrompt是个很好的sql server提示工具,SQL-SERVER2016只能使用SQLPrompt7.x 以上版本,用激活工具激活后没多久就会检测到激活码不可用.所以感觉是不是有个服务在 ...

  7. 理解volatile与synchronized

    用 volatile 修饰的变量可以保证线程的"可见性",也就是,任何线程修改了这个 volatile 修饰的值都会通知其他线程来主缓存中重新读取值. 下面通过例子加以说明: pu ...

  8. PHP处理mysql事务

    MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事务rollback 事务回滚commit 事务确认2.直接用set来改变mysql的自动 ...

  9. dategrip破解

    https://blog.csdn.net/weixin_39428938/article/details/81078806

  10. 文档-linux io模式及select,poll,epoll

    文档-Linux IO模式详解 1. 概念说明 在进行解释之前,首先要说明几个概念:- 用户空间和内核空间- 进程切换- 进程的阻塞- 文件描述符- 缓存 I/O 1.1 用户空间与内核空间 现在操作 ...