6 获取backend的所有节点名; get_backend_name
流程图:
源码;
haconfig.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import shutil import re _default_path = os.path.dirname(os.path.abspath("__file__")) class haproxy(object): _default_path = os.path.dirname(os.path.abspath("__file__")) _default_file = os.path.join(_default_path, "config.ini") _tmp_file = os.path.join(_default_path, "tmp.ini") def __init__(self, ip='', weight=20, max_conn=100, file=_default_file): self.config_file = file self.ip_address = ip self.weight = weight self.max_conn = max_conn self.backend_contant = '' self.backend_name = list() # 检查ip是否合法,变为一个属性 @property def check_ip_available(self): rule = "((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$" # (200-240 | 250- 255|0-199|). 重复3次 IP r = re.compile(rule) if r.match(self.ip_address): return True else: return False # 拼接字符串 def union_str(self): """ 添加或修改backend的内容时,调用此类方法,将输入的参数值拼接成一行完成配置信息 :return: 更新到self.backend_value属性中, """ _default_str = 'server {ip} {ip} weight {weight} maxconn {maxconn}' self.backend_contant = _default_str.format(ip=self.ip_address, weight=self.weight, maxconn=self.max_conn) def get_backend_name(self): """ 获取配置文件中的所有 backend 节点信息 :return: 无返回值,保存在 self.backend_name 中 """ with open(self.config_file, 'r') as fr: for line in fr: if line.startswith("backend"): self.backend_name.append(line.split()[1]) # 查找指定 backend 节点下的配置信息 def show_backend(self, backend): """ 根据用户输入的 backend 节点值获取对应的配置文件 :param backend: 查找的键值,如: test.oldboy.org :return: 返回一个列表 list """ result = list() # 定位到查找的行标识 line_locked_flag = False with open(self.config_file, 'r', encoding='utf-8') as f: for line in f: # 如果找到 backend 配置节 if line.startswith('backend'): # 获取backend的内容,test.oldboy.com url_addr = line.split()[1] # 如果内容和搜索的内容一样,则将定位标识置为True if url_addr == backend: line_locked_flag = True continue else: line_locked_flag = False # 如果定位到内容则将配置写入到结果列表中 if line_locked_flag: result.append(line) return result # 增加backend内容 def add_backend(self, backend): """ 根据输入的backend查找文件: 如果存在 backend,则在配置末尾增加一条记录 如果不存在 backend,则在最后新增加一个 :param backend: 要增加的backend,如:test.oldboy.com :return: """ # 是否存在指定的backend标识,如果存在就在指定下面添加配置,没有就新建一个backend,再添加配置 backend_is_exists_flag = False # 定位到查找的行标识 line_locked_flag = False try: with open(self.config_file, 'r') as fr,open(self._tmp_file, 'a+') as fw: for line in fr: if line.startswith('backend'): url_addr = line.split()[1] if url_addr == backend: backend_is_exists_flag = True line_locked_flag = True else: # 找到"backend"字符标识,且定位标识为True,说明到了定位的下一个backend,这时需要先追加一条配置 if line_locked_flag: fw.write(" {content}\n".format(content=self.backend_contant)) line_locked_flag = False fw.write(line) # 文件中没有要添加的 backend 节点,那在最后新增加一个节点 if not backend_is_exists_flag: fw.write("backend {url}\n".format(url=backend)) fw.write(" {content}\n".format(content=self.backend_contant)) # 将临时文件重命名,替换原来的配置文件 shutil.move(self._tmp_file, self.config_file) return True except Exception as e: return e # 删除指定 backend 的配置 def del_backend(self, backend): is_locked_flag = False # 是否找到指定的 IP 配置信息 is_delete_flag = False try: with open(self.config_file, 'r') as fr, open(self._tmp_file, 'a+') as fw: for line in fr: # 找到backend行 if line.startswith("backend"): url_addr = line.split()[1] # 找到指定的backend节点 if url_addr == backend: is_locked_flag = True else: # 找到指定 backend 节点的下一个backend, 定位标识别改为False if is_locked_flag: is_locked_flag = False else: if is_locked_flag: # 在定位的 backend 节点下找到符合的 IP ,则把这一行跳过,不写到tmp文件中 if line.count(self.ip_address) > 0: is_delete_flag = True continue fw.write(line) shutil.move(self._tmp_file, self.config_file) if not is_delete_flag: return False else: return True except Exception as e: return e
Modify_ini.py:
#!/usr/bin/env python # -*- coding: utf-8 -*- from haconfig import haproxy welcome_title_str = "%s\n#%s#\n#%s#\n#%s#\n%s" % ("".ljust(50, '#'), ''.ljust(48, ' '), 'HAProxy 配置管理程序'.center(43, ' '), ''.ljust(48, ' '), ''.ljust(50, '#') ) menu_str = "\n1.查找配置\n2.添加配置\n3.删除配置\n4.退出程序\n" # 返回一个非空的输入 def input_string(show_message, is_int=False): """ 对input函数进行重新改造,增加判断不能为空, :param show_message: input()中的提示信息 :param is_int: 是否要求输入必须为数字,默认为False,如果为True就要检查是否为数字 :return: 返回用户输入的值 """ not_null_flag = False while not not_null_flag: # 获得用户的输入信息 input_value = input("{message}".format(message=show_message)).strip().lower() if not input_value: continue else: # 如果要求输入必须为数字,则做以下验证 if is_int: if not input_value.isdigit(): print("\n\033[1;30m非法输入,请输入一个数字!\033[0m") continue not_null_flag = True return input_value if __name__ == "__main__": print(welcome_title_str) # 退出系统标识 exit_flag = False while not exit_flag: print(menu_str) choose = input("请选择功能模块:").strip().lower() # 退出系统 if choose == '4': exit_flag = True continue if choose not in ('1', '2', '3'): print("\n\033[1;31m输入错误!请输入正确的功能编号.\033[0m") else: # 实例化配置文件对象 proxyobj = haproxy() # 1. 查找节点配置信息 if choose == "1": # 获取所有 backend 的节点名称 proxyobj.get_backend_name() print("\n当前配置文件所有 backend 节点名称:") for name in proxyobj.backend_name: print(name) search_backend = input_string("\n请输入要查找的 backend 域名:") # 调用类方法获取配置信息列表 search_result = proxyobj.show_backend(search_backend) if not search_result: print("\n\033[1;30m没有找到要查找的记录!\033[1m\n ") else: for record in search_result: print(record.strip()) # 2. 添加配置 if choose == "2": search_backend = input_string("请输入要添加的 backend 域名:") # 对配置文件对象进行赋值 proxyobj.ip_address = input_string("请输入添加的 IP 地址:") # 判断IP是否合法 while not proxyobj.check_ip_available: proxyobj.ip_address = input_string("\nIP地址不合法! 请重新输入 IP 地址:") proxyobj.weight = input_string("请输入添加的 weight 值:", is_int=True) proxyobj.max_conn = input_string("请输入添加的 max conn 值:", is_int=True) # 根据用户输入的信息,调用类的格式化字符串方法生成配置文件串 proxyobj.union_str() # 调用添加方法进行添加配置操作 if proxyobj.add_backend(search_backend): print("\n添加成功! 节点当前配置更新为:") # 将添加成功的信息打印出来,直接调用类的查看方法 search_result = proxyobj.show_backend(search_backend) for line in search_result: print(line.strip()) # 3. 删除配置 if choose == "3": # 重新获取一下当前配置文件中的节点名称列表 proxyobj.get_backend_name() # 要删除的 backend 节点是否存在标识 is_exist_flag = False while not is_exist_flag: search_backend = input_string("请指定要删除配置的 backend 节点名称: ") if search_backend not in proxyobj.backend_name: print("\n当前配置文件中未找到 %s 的 backend 节点!" %search_backend) continue else: is_exist_flag = True proxyobj.ip_address = input_string("请输入要删除的 IP 地址:") # 判断IP是否合法 while not proxyobj.check_ip_available: proxyobj.ip_address = input_string("\nIP地址不合法! 请重新输入 IP 地址:") # 调用类的删除方法进行删除操作 if proxyobj.del_backend(search_backend): print("\n删除成功!当前节点配置更新为: ") else: print("\n删除失败!请检查 IP 地址是否存在!\n") # 将修改后的信息打印出来,直接调用类的查看方法 search_result = proxyobj.show_backend(search_backend) for line in search_result: print(line.strip())