需求
- 根据用户输入输出对应的backend下的server信息
- 可添加backend 和sever信息
- 可修改backend 和sever信息
- 可删除backend 和sever信息
- 操作配置文件前进行备份
- 加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