#!/usr/bin/env python
import os,sys,time,re,prettytable,json
from collections import defaultdict,OrderedDict
conf='haproxy.cfg'  ###指定haproxy配置文件###
jgf=''
######################1.input输入字符类型转化函数#######################
def input_handle(s):
    if str.isdigit(s):                                                     ###对输入是否是数字进行判断###
        s = int(s)                                                         ###如果输出的是个数字,则转化为整数类型###
    return s                                                              ###返回输入字符###

###########################2.backend列表展示函数############################
def backend_read(conf):
    backend_list = []                                                       ###初始化backend的列表###
    show_dict = {}                                                          ###初始化要返回的显示字典###
    backend_name_dict = defaultdict(list)                                   ###定义一个value为列表的字典,用来存放server###
    server_flag = False                                                     ###初始化server判断标志位###
    with open(conf,'r') as ha:                                             ###打开haproxy配置文件###
        for line in ha:
            server_dict = OrderedDict()                                      ###定义一个有序字典###
            line = line.strip('\n')
            #情况1
            if re.match('backend',line):                                    ###匹配配置文件以backend开头的行###
                backend_name = re.split('\s+',line)[1]
                backend_list.append(backend_name)                            ###将配置到的backend的名称插入到列表###
                server_flag = True                                           ###赋值标志位为真,用来与server关联###
            #情况2
            elif server_flag and re.match('\s+server',line):               ###匹配配置文件以server开头的行###
                server_info = re.split('\s+',line)                          ###对server进行分隔###
                server_dict['name'] = server_info[2]                        ###对server的具体信息进行字典赋值###
                server_dict['address'] = server_info[3]
                server_dict['weight'] = server_info[5]
                server_dict['maxconn'] = server_info[7]
                backend_name_dict[backend_name].append(server_dict)          ###将server字典与backend的名称进行关联###
            else:
                server_flag = False                                          ###当server没匹配到,赋值标志位为假,结束关联###
    for k,v in enumerate(backend_list,1):
        show_dict[k] = v                                                     ###对backend名称进行新字典赋值,方便查询和展示###
        print('%d . %s' % (k,v))                                             ###输出backend列表###
    return(show_dict,backend_name_dict)                                     ###返回显示的字典和backend-server字典###

########################3.显示server服务器函数#############################
def backend_server_show(backend_show_value,server_show_dict):
    ############对backend名称进行遍历并加上数字编号###########################
    print(jgf.center(70,'='))
    print('\033[1m后端服务器(%s)信息如下:\033[0m'%backend_show_value)
    print('%-20s %-20s %-20s %-20s'%('name','address','weight','maxconn'))
    server_list = server_show_dict[backend_show_value]
    for v in server_list:                                     ###用enumerate进行server展示###
        n=list(v.values())
        print('\033[32;40m%-5s%20s%15s%25s\033[1m'%(n[0],n[1],n[2],n[3]))
    print(jgf.center(60, '='))

#####################4.名称输入判断函数#############################
def name_decide():
    (name,name_flag) = ('',True)                                           ###初始化返回的名称和判断标志位###
    while name_flag:
        name_input = input('\033[32m请输入新服务名(退出输入q):\033[0m')
        if len(name_input) == 0:                                           ###如果输入为空则直接下一次循环###
            continue
        elif name_input == 'q':                                           ###输入q,退出本次输入###
            name_flag = False
            sys.exit('\033[32;1m脚本已退出!\033[1m')
        elif re.match('[0-9a-zA-Z\_]+',name_input):                       ###匹配输入是否以字符、数字或下划线开头###
            name = name_input
            name_flag = False                                              ###输入成功后退出循环###
        else:
            print('\033[31m名称输入错误,请重新输入!!!\033[0m')
        break
    return(name)                                                          ###返回输入的结果###
#####################5.IP地址及端口输入判断函数#############################
def ipaddress_decide():
    (address,address_flag) = ('',True)                                     ###初始化返回的IP地址和判断标志位###
    while address_flag:
        address_input = input('\033[32m请输入新地址(IP哦)(退出输入q):\033[0m')
        if len(address_input) == 0:                                        ###如果输入为空则直接下一次循环###
            continue
        elif address_input == 'q':                                        ###输入q,退出本次输入###
            address_flag = False
            sys.exit('\033[32;1m脚本已退出!\033[1m')
        ##################匹配输入是否是ip:port的格式######################
        elif re.match('(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}(\:\d{1,5})?$',address_input):
            address = address_input
            address_flag = False                                           ###输入成功后退出循环###
        else:
            print('\033[31m地址输入错误,请重新输入!!!\033[0m')
    return(address)                                                       ###返回输入的结果###

####################6.数字输入判断函数######################################
def number_decide(name):
    (number,number_flag) = ('',True)                                      ###初始化返回的数字和判断标志位###
    while number_flag:
        number_input =input('\033[32m请输入%s(数字哦)(退出输入q):\033[0m' % name)
        if len(number_input) == 0:                                        ###如果输入为空则直接下一次循环###
            continue
        elif number_input == 'q':                                        ###输入q,退出本次输入###
            number_flag = False
            sys.exit('\033[32;1m脚本已退出!\033[32;1m')
        else:
            try:
                int(number_input)                                         ###匹配输入是否是数字###
            except:
                print('\033[31;1m%s输入类型错误,请重新输入!!!\033[0m'%name)
            else:
                number = number_input
                number_flag = False                                       ###输入成功后退出循环###
    return(number)                                                       ###返回输入的结果###

#############################7.节点输入判断函数##########################
def backend_input_if(input_index,input_dict):
    (input_name,input_flag) = ('',True)                                   ###初始化返回的名称和判断标志位###
    ###############如果输入非空,对输入进行判断并转化类型#################
    if len(input_index) != 0:
        input_index = input_handle(input_index)
    if input_index == 'b':                                                ###如果输入为b,则退出程序###
        input_flag = False
    elif input_index in input_dict.keys():                                ###如果输入为数字编号,则从字典中获取具体backend名称###
        input_name = input_dict[input_index]
    elif input_index in input_dict.values():                              ###如果输入为backend名称,则直接获取###
        input_name = input_index
    else:
        input_name = ''                                                    ###输入其他字符,赋值变量为空###
    return(input_name,input_flag)                                         ###返回输入的结果和循环标志位###

########################8.配置文件操作函数#################
def backend_server_handle(conf,handle_dict):
    newfile = '%s.new'%conf                                                ###定义回写的新文件###
    server_flag = False
    with open(conf,'r') as read_file,open(newfile,'w') as write_file:       ###同时打开二文件,一个读,一个写###
        for line in read_file:
            if re.match('backend',line):                                     ###匹配到backend行时进行server信息插入###
                write_file.write(line)
                backend_name = re.split('\s+',line)[1]
                for server_dict in handle_dict[backend_name]:                ###对backend-server字典进行遍历###
                    server_line = '\tserver {name} {address} weight {weight} maxconn {maxconn}\n'
                    write_file.write(server_line.format(**server_dict))       ###将指定的backend下的server条目插入文件###

server_flag = True                                           ###指定标志位为真,方便server判断###
            elif server_flag and re.match('\s+server',line):                 ###匹配server开头的行,跳过不做任何操作###
                pass
            else:
                write_file.write(line)                                        ###其他的行,直接插入新文件###
                server_flag = False
    print('\033[33;1m server更新成功\033[0m')
    os.system('mv %s %s.bak'%(conf,conf))                                  ###对源配置文件进行备份###
    os.system('mv %s %s'%(newfile,conf))                                   ###对新生成的配置文件进行改名###

##################################主程序开始##################################
if __name__ == '__main__':
    flag = True
    backend_name = ''
    haproxy_name_show_dict = {}                                                ###初始化backend显示字典###
    haproxy_server_show_dict = {}                                              ###初始化server显示字典###
    while flag:
        print(jgf.center(60,'='))
        hy='\033[36m欢迎访问haproxy配置文件管理脚本\033[0m'
        print(hy.center(60,'*'))
        print('\033[1mbackend列表信息如下:')
        (haproxy_name_show_dict,haproxy_server_show_dict) = backend_read(conf)
        print(jgf.center(50,'='))
        time.sleep(1)
        print('''
        \033[35;1m1.查询后端服务\033[0m
        \033[35;1m 2.添加后端服务\033[0m
        \033[35;1m 3.修改后端服务\033[0m
        \033[31;1m 4.删除后端服务\033[0m
        \033[32;1m 5.退出\033[0m ''')
        print(jgf.center(60,'='))
        select_num = input('\033[35;1m请选择操作条目:\033[0m')

#######################1. 查询后端服务################################
        if select_num == '1':
            query_flag = True                                                 ###初始化查询循环标志###
            while query_flag:
                backend_index =input('\033[31;1m请输入需要查询的backend编号或名称(返回上级菜单输入b,退出输入q):\033[0m')

##############################对输入值进行判断################
                (backend_name,query_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
                if backend_name:                                              ###显示对应backend下的server列表###
                    backend_server_show(backend_name,haproxy_server_show_dict)
                elif backend_index=='b':
                    break
                elif backend_index=='q':
                    sys.exit('\033[35;1m脚本退出!\033[0m')
                else:
                    query_flag=False
                    print('\033[31;1m您输入的节点不存在!请重新输入!')
                    time.sleep(1)

#######################2. 添加后端服务################################
        if select_num == '2':
            add_flag = True                                                   ###初始化添加循环标志###
            while add_flag:
                backend_index =input('\033[32;1m请输入添加的backend的编号或名称(返回上级菜单,请输入b):\033[0m')
                ##############################对输入值进行判断################
                (backend_name,add_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
                if backend_name:                                              ###显示对应backend下的server列表###
                    backend_server_show(backend_name,haproxy_server_show_dict)
                    add_server_dict = OrderedDict()                           ###设置实例默认为有序字典
                    print('\033[34;1m请依次输入后端服务信息(name,address,weight,maxconn):\033[0m')
                    add_server_dict['name'] = name_decide()                  ###对输入的name有效性进行判断###
                    add_server_dict['address'] = ipaddress_decide()          ###对输入的IP有效性进行判断###
                    add_server_dict['weight'] = number_decide('权重值')      ###对输入的权重有效性进行判断###
                    add_server_dict['maxconn'] = number_decide('最大连接数') ###对输入的连接数有效性进行判断###

print(add_server_dict['name'],add_server_dict['address'],add_server_dict['weight'],add_server_dict['maxconn'])

#############对输入的四个服务信息是否成功判断#############
                    if add_server_dict['name'] and add_server_dict['address'] and add_server_dict['weight'] and add_server_dict['maxconn']:
                        add_commit = input('\033[31;1m请确认是否添加此条目(y | n):\033[0m')
                        if add_commit == 'y':                                 ###确认添加服务条目,并回写配置文件###
                            haproxy_server_show_dict[backend_name].append(add_server_dict)
                            backend_server_handle(conf,haproxy_server_show_dict)
                        else:
                            add_flag = False                                  ###否则退出本次循环###
                    else:
                        print('\033[1;31m server信息输入有误,请重新输入!!!\033[0m')
                        time.sleep(2)

#######################3. 修改后端服务#################################
        if select_num == '3':
            backend_modify_flag = True                                         ###初始化修改循环标志###
            while backend_modify_flag:
                backend_index =input('\033[32;1m请输入修改的backend的编号或名称(返回上级菜单,请输入b):\033[0m')
                ##############################对输入值进行判断################
                (backend_name,backend_modify_flag) = backend_input_if(backend_index,haproxy_name_show_dict)

if backend_name:                                               ###显示对应backend下的server列表###
                    backend_server_show(backend_name,haproxy_server_show_dict)

server_modify_flag = True                                  ###初始化server条目修改标志位###
                    while server_modify_flag:

server_index =input('\033[32;1m请输入修改的server的编号(返回上级菜单,请输入b):\033[0m')
                        if len(server_index) != 0:
                            server_index = input_handle(server_index)
                        if server_index == 'b':                               ###输入b,返还上一层###
                            server_modify_flag = False
                        #####################指定具体的server编号进行判断#####
                        elif server_index >= 1 and server_index <= len(haproxy_server_show_dict[backend_name]):
                            modify_server_dict = OrderedDict()
                            print('\033[34;1m请依次输入后端服务信息(name,address,weight,maxconn):\033[0m')
                            modify_server_dict['name'] = name_decide()        ###对输入的四个信息有效性进行判断###
                            modify_server_dict['address'] = ipaddress_decide()
                            modify_server_dict['weight'] = number_decide('权重值')
                            modify_server_dict['maxconn'] = number_decide('最大连接数')

print(modify_server_dict['name'],modify_server_dict['address'],modify_server_dict['weight'],modify_server_dict['maxconn'])

######对输入的四个服务信息是否成功判断#############
                            if modify_server_dict['name'] and modify_server_dict['address'] and modify_server_dict['weight'] and modify_server_dict['maxconn']:
                                modify_commit =input('\033[32;1m请确认是否修改此条目(y|n):\033[1m')
                                if modify_commit == 'y':                      ###确认修改服务条目,并回写配置文件###
                                    haproxy_server_show_dict[backend_name][server_index - 1] = modify_server_dict
                                    backend_server_handle(conf,haproxy_server_show_dict)
                                    modify_server_flag = False

else:                                         ###否则退出本次循环###
                                    modify_server_flag = False
                            else:
                                print('\033[31m server输入信息有误,请重新输入!!!\033[0m')
                        else:
                            print('\033[31m server编号输入错误,请重新输入!!!\033[0m')

#######################4. 删除后端服务################################
        if select_num == '4':
            backend_delete_flag = True                                        ###初始化删除循环标志###
            while backend_delete_flag:
                backend_index =input('\033[32;1m请输入删除的backend下条目编号或名称(返回上层菜单,请输入b):\033[0m')
                ##############################对输入值进行判断################
                (backend_name,backend_delete_flag) = backend_input_if(backend_index,haproxy_name_show_dict)

if backend_name:                                              ###显示对应backend下的server列表###
                    backend_server_show(backend_name,haproxy_server_show_dict)

server_delete_flag = True                                 ###初始化server条目删除标志位###
                    while server_delete_flag:

server_index =input('\033[32;1m请输入要删除的server编号(返回上层菜单,请输入b):\033[0m')
                        if len(server_index) != 0:
                            server_index = input_handle(server_index)
                        if server_index == 'b':                               ###输入b,返还上一层###
                            server_delete_flag = False
                        #####################指定具体的server编号进行判断#####
                        elif server_index >= 1 and server_index <= len(haproxy_server_show_dict[backend_name]):

print(haproxy_server_show_dict[backend_name][server_index - 1])
                            delete_commit =input('请确认是否删除此条目(y|n):')
                            if delete_commit == 'y':                          ###确认删除服务条目,并回写配置文件###
                                del haproxy_server_show_dict[backend_name][server_index - 1]
                                backend_server_handle(conf,haproxy_server_show_dict)
                                delete_server_flag = False

else:                                             ###否则退出本次循环###
                                delete_server_flag = False
                        else:
                            print('\033[31m server编号输入错误,请重新输入!!!\033[0m')

#######################5. 退出程序######################
        if select_num == '5':
           print('\033[31;1m程序将在两秒后退出,欢迎再次使用,谢谢!\033[0m')
           time.sleep(1)
           print('\033[32;1m1s\033[0m')
           time.sleep(1)
           print('\033[32;1m2s\033[0m')
           print('\033[31;1m程序退出')
           sys.exit()

转载于:https://www.cnblogs.com/chenghao1994/p/7237879.html

haproxy配置文件管理脚本相关推荐

  1. redis sentinel集群配置及haproxy配置

    ip分布情况: sentinel-1/redis 主 10.11.11.5 sentinel-2/redis 从 10.11.11.7 sentinel-3/redis 从 10.11.11.8 ha ...

  2. CENTOS7 高性能Linux集群 通过yum进行 haproxy配置 !安装 !使用!HAProxy配置文件详解

    Haproxy配置 永久修改名字:便于区分虚拟机! Haproxy:hostnamectl set-hostname haproxy Web1: hostnamectl set-hostname WE ...

  3. Haproxy配置http模式负载均衡

    环境准备: 主机名 角色 IP地址 mylinux1.contoso.com haproxy服务器 eth0:192.168.100.121 eth1:172.16.100.121 mylinux3. ...

  4. Haproxy 配置详解

    http://www.07net01.com/linux/Haproxypeizhixiangjie_645322_1380518936.html HAProxy提供高可用性.负载均衡以及基于TCP和 ...

  5. nagios监控haproxy(借助脚本)

    nagios监控haproxy(借助脚本) 修改后的脚本如下(需添加指示灯的状态) # vi haproxy.sh #!/bin/bash Port=`netstat -ntpl | grep hap ...

  6. 用友云微服务架构下配置文件管理利器:配置中心

    微服务架构是这几年IT领域的一个高频词汇,越来越多的项目和应用正在以微服务的思想进行重构.相比于单体应用和SOA架构,微服务优势也逐渐凸显,被广大架构师和技术人员引入和推崇.当然,单体应用.SOA.微 ...

  7. 【Android FFMPEG 开发】FFMPEG 交叉编译配置 ( 下载 | 配置脚本 | 输出路径 | 函数库配置 | 程序配置 | 组件配置 | 编码解码配置 | 交叉编译配置 | 最终脚本 )

    文章目录 一.FFMPEG 源码下载 解压 二.交叉编译工具 三.configure 脚本及帮助命令 四.配置 configure 脚本 五.输出目录配置 六.函数库配置 七.程序配置选项 八.组件配 ...

  8. 【Android NDK 开发】Android Studio 的 NDK 配置 ( 源码编译配置 | 构建脚本配置 | 打包配置 | CMake 配置 | ndkBuild 配置 )

    文章目录 I . 源码编译配置 II . 构建脚本配置 III . NDK 函数库打包配置 IV . Java 与 C 代码示例 V . CMake 配置 ( CMakeLists.txt ) VI ...

  9. CentOS 7配置LNMP开发环境及配置文件管理详解

    本篇文章主要介绍了CentOS 7配置LNMP开发环境及配置文件管理,详细的介绍了MySQL 5.6,PHP 5.6,Nginx的安装与配置,有兴趣的可以了解一下. 安装并配置MySQL 5.6 从C ...

最新文章

  1. E: GPG 错误:http://developer.download.nvidia.com Release: 下列签名无效: NODATA 1 NODATA 2...
  2. 【译】A quick list of new enterprise features in iOS 13, iPadOS, and macOS 10.15 Catalina
  3. pq 中m函数判断嵌套_Python中numpy的布尔判断、切片、维度变化、合并、通用函数...
  4. teamview修改id
  5. 日常护理常识以及化妆品的选购 - 健康程序员,至尚生活!
  6. 容器系列之虚拟化网络
  7. 转载]:[面试题:接口和抽象类的区别
  8. Python读写Excel简单案例及调试说明文档
  9. 四种JAVA架构演进史,程序员能学会最后一种就非常厉害了,至少50k
  10. Carry On My Wayward Son -- Kansas
  11. python是面向对象开发_Python开发之路-面向对象
  12. 取色器插件 react-color ChromePicker
  13. 《Total Commander:万能文件管理器》——12.6. 附录
  14. 2. linux默认的系统管理员账号是,2019.10第二周 王俊懿_Linux
  15. 适合小程序定制的企业有哪些?
  16. 七、ROS-CAN通信
  17. javascript(JS) 0基础快速入门 (二)(this指向问题)
  18. 前缀、中缀、后缀表达式
  19. ZUCC_计算机网络实验_实验01 实验一RJ45原理与制作
  20. CentOS 7系统安装Ghost

热门文章

  1. 一般将来时语法课教案_优秀教案人教版必修二Unit2——语法专题课训练
  2. 东南大学微型计算机期末,12级东南大学微机期中试卷
  3. cpu利用率低linux,linux计算,cpu 利用率超低,如何处理?
  4. java8种基本类型长度_【Java基础】Java的8种基本数据类型深入介绍
  5. mysql optimize 用法_mysql中OPTIMIZE TABLE的作用
  6. xx是一个类型 这在给定的上下文_#PaperCarrier | CoSeRNN :为你解释序列化与上下文在会话推荐中的作用...
  7. windows7卸载linux系统,win7下安全卸载linux系统
  8. spring boot 教程(三)配置详解
  9. pulse 去马赛克软件_打马赛克就安全了吗?AI消除马赛克,上线三天收获近7000星...
  10. docker 启动镜像_Docker学以致用,开源项目和云服务,是最好的学习资源