• Python-day3作业-haproxy配置文件管理脚本


      1 #!/usr/bin/env python
      2 import os,sys,time,re,prettytable,json
      3 from collections import defaultdict,OrderedDict
      4 conf='haproxy.cfg'  ###指定haproxy配置文件###
      5 jgf=''
      6 ######################1.input输入字符类型转化函数#######################
      7 def input_handle(s):
      8     if str.isdigit(s):                                                     ###对输入是否是数字进行判断###
      9         s = int(s)                                                         ###如果输出的是个数字,则转化为整数类型###
     10     return s                                                              ###返回输入字符###
     11 
     12 ###########################2.backend列表展示函数############################
     13 def backend_read(conf):
     14     backend_list = []                                                       ###初始化backend的列表###
     15     show_dict = {}                                                          ###初始化要返回的显示字典###
     16     backend_name_dict = defaultdict(list)                                   ###定义一个value为列表的字典,用来存放server###
     17     server_flag = False                                                     ###初始化server判断标志位###
     18     with open(conf,'r') as ha:                                             ###打开haproxy配置文件###
     19         for line in ha:
     20             server_dict = OrderedDict()                                      ###定义一个有序字典###
     21             line = line.strip('
    ')
     22             #情况1
     23             if re.match('backend',line):                                    ###匹配配置文件以backend开头的行###
     24                 backend_name = re.split('s+',line)[1]
     25                 backend_list.append(backend_name)                            ###将配置到的backend的名称插入到列表###
     26                 server_flag = True                                           ###赋值标志位为真,用来与server关联###
     27             #情况2
     28             elif server_flag and re.match('s+server',line):               ###匹配配置文件以server开头的行###
     29                 server_info = re.split('s+',line)                          ###对server进行分隔###
     30                 server_dict['name'] = server_info[2]                        ###对server的具体信息进行字典赋值###
     31                 server_dict['address'] = server_info[3]
     32                 server_dict['weight'] = server_info[5]
     33                 server_dict['maxconn'] = server_info[7]
     34                 backend_name_dict[backend_name].append(server_dict)          ###将server字典与backend的名称进行关联###
     35             else:
     36                 server_flag = False                                          ###当server没匹配到,赋值标志位为假,结束关联###
     37     for k,v in enumerate(backend_list,1):
     38         show_dict[k] = v                                                     ###对backend名称进行新字典赋值,方便查询和展示###
     39         print('%d . %s' % (k,v))                                             ###输出backend列表###
     40     return(show_dict,backend_name_dict)                                     ###返回显示的字典和backend-server字典###
     41 
     42 ########################3.显示server服务器函数#############################
     43 def backend_server_show(backend_show_value,server_show_dict):
     44     ############对backend名称进行遍历并加上数字编号###########################
     45     print(jgf.center(70,'='))
     46     print('33[1m后端服务器(%s)信息如下:33[0m'%backend_show_value)
     47     print('%-20s %-20s %-20s %-20s'%('name','address','weight','maxconn'))
     48     server_list = server_show_dict[backend_show_value]
     49     for v in server_list:                                     ###用enumerate进行server展示###
     50         n=list(v.values())
     51         print('33[32;40m%-5s%20s%15s%25s33[1m'%(n[0],n[1],n[2],n[3]))
     52     print(jgf.center(60, '='))
     53 
     54 #####################4.名称输入判断函数#############################
     55 def name_decide():
     56     (name,name_flag) = ('',True)                                           ###初始化返回的名称和判断标志位###
     57     while name_flag:
     58         name_input = input('33[32m请输入新服务名(退出输入q):33[0m')
     59         if len(name_input) == 0:                                           ###如果输入为空则直接下一次循环###
     60             continue
     61         elif name_input == 'q':                                           ###输入q,退出本次输入###
     62             name_flag = False
     63             sys.exit('33[32;1m脚本已退出!33[1m')
     64         elif re.match('[0-9a-zA-Z\_]+',name_input):                       ###匹配输入是否以字符、数字或下划线开头###
     65             name = name_input
     66             name_flag = False                                              ###输入成功后退出循环###
     67         else:
     68             print('33[31m名称输入错误,请重新输入!!!33[0m')
     69         break
     70     return(name)                                                          ###返回输入的结果###
     71 #####################5.IP地址及端口输入判断函数#############################
     72 def ipaddress_decide():
     73     (address,address_flag) = ('',True)                                     ###初始化返回的IP地址和判断标志位###
     74     while address_flag:
     75         address_input = input('33[32m请输入新地址(IP哦)(退出输入q):33[0m')
     76         if len(address_input) == 0:                                        ###如果输入为空则直接下一次循环###
     77             continue
     78         elif address_input == 'q':                                        ###输入q,退出本次输入###
     79             address_flag = False
     80             sys.exit('33[32;1m脚本已退出!33[1m')
     81         ##################匹配输入是否是ip:port的格式######################
     82         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):
     83             address = address_input
     84             address_flag = False                                           ###输入成功后退出循环###
     85         else:
     86             print('33[31m地址输入错误,请重新输入!!!33[0m')
     87     return(address)                                                       ###返回输入的结果###
     88 
     89 ####################6.数字输入判断函数######################################
     90 def number_decide(name):
     91     (number,number_flag) = ('',True)                                      ###初始化返回的数字和判断标志位###
     92     while number_flag:
     93         number_input =input('33[32m请输入%s(数字哦)(退出输入q):33[0m' % name)
     94         if len(number_input) == 0:                                        ###如果输入为空则直接下一次循环###
     95             continue
     96         elif number_input == 'q':                                        ###输入q,退出本次输入###
     97             number_flag = False
     98             sys.exit('33[32;1m脚本已退出!33[32;1m')
     99         else:
    100             try:
    101                 int(number_input)                                         ###匹配输入是否是数字###
    102             except:
    103                 print('33[31;1m%s输入类型错误,请重新输入!!!33[0m'%name)
    104             else:
    105                 number = number_input
    106                 number_flag = False                                       ###输入成功后退出循环###
    107     return(number)                                                       ###返回输入的结果###
    108 
    109 #############################7.节点输入判断函数##########################
    110 def backend_input_if(input_index,input_dict):
    111     (input_name,input_flag) = ('',True)                                   ###初始化返回的名称和判断标志位###
    112     ###############如果输入非空,对输入进行判断并转化类型#################
    113     if len(input_index) != 0:
    114         input_index = input_handle(input_index)
    115     if input_index == 'b':                                                ###如果输入为b,则退出程序###
    116         input_flag = False
    117     elif input_index in input_dict.keys():                                ###如果输入为数字编号,则从字典中获取具体backend名称###
    118         input_name = input_dict[input_index]
    119     elif input_index in input_dict.values():                              ###如果输入为backend名称,则直接获取###
    120         input_name = input_index
    121     else:
    122         input_name = ''                                                    ###输入其他字符,赋值变量为空###
    123     return(input_name,input_flag)                                         ###返回输入的结果和循环标志位###
    124 
    125 ########################8.配置文件操作函数#################
    126 def backend_server_handle(conf,handle_dict):
    127     newfile = '%s.new'%conf                                                ###定义回写的新文件###
    128     server_flag = False
    129     with open(conf,'r') as read_file,open(newfile,'w') as write_file:       ###同时打开二文件,一个读,一个写###
    130         for line in read_file:
    131             if re.match('backend',line):                                     ###匹配到backend行时进行server信息插入###
    132                 write_file.write(line)
    133                 backend_name = re.split('s+',line)[1]
    134                 for server_dict in handle_dict[backend_name]:                ###对backend-server字典进行遍历###
    135                     server_line = '	server {name} {address} weight {weight} maxconn {maxconn}
    '
    136                     write_file.write(server_line.format(**server_dict))       ###将指定的backend下的server条目插入文件###
    137 
    138                 server_flag = True                                           ###指定标志位为真,方便server判断###
    139             elif server_flag and re.match('s+server',line):                 ###匹配server开头的行,跳过不做任何操作###
    140                 pass
    141             else:
    142                 write_file.write(line)                                        ###其他的行,直接插入新文件###
    143                 server_flag = False
    144     print('33[33;1m server更新成功33[0m')
    145     os.system('mv %s %s.bak'%(conf,conf))                                  ###对源配置文件进行备份###
    146     os.system('mv %s %s'%(newfile,conf))                                   ###对新生成的配置文件进行改名###
    147 
    148 ##################################主程序开始##################################
    149 if __name__ == '__main__':
    150     flag = True
    151     backend_name = ''
    152     haproxy_name_show_dict = {}                                                ###初始化backend显示字典###
    153     haproxy_server_show_dict = {}                                              ###初始化server显示字典###
    154     while flag:
    155         print(jgf.center(60,'='))
    156         hy='33[36m欢迎访问haproxy配置文件管理脚本33[0m'
    157         print(hy.center(60,'*'))
    158         print('33[1mbackend列表信息如下:')
    159         (haproxy_name_show_dict,haproxy_server_show_dict) = backend_read(conf)
    160         print(jgf.center(50,'='))
    161         time.sleep(1)
    162         print('''
    163         33[35;1m1.查询后端服务33[0m
    164         33[35;1m 2.添加后端服务33[0m
    165         33[35;1m 3.修改后端服务33[0m
    166         33[31;1m 4.删除后端服务33[0m
    167         33[32;1m 5.退出33[0m ''')
    168         print(jgf.center(60,'='))
    169         select_num = input('33[35;1m请选择操作条目:33[0m')
    170 
    171         #######################1. 查询后端服务################################
    172         if select_num == '1':
    173             query_flag = True                                                 ###初始化查询循环标志###
    174             while query_flag:
    175                 backend_index =input('33[31;1m请输入需要查询的backend编号或名称(返回上级菜单输入b,退出输入q):33[0m')
    176 
    177                 ##############################对输入值进行判断################
    178                 (backend_name,query_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
    179                 if backend_name:                                              ###显示对应backend下的server列表###
    180                     backend_server_show(backend_name,haproxy_server_show_dict)
    181                 elif backend_index=='b':
    182                     break
    183                 elif backend_index=='q':
    184                     sys.exit('33[35;1m脚本退出!33[0m')
    185                 else:
    186                     query_flag=False
    187                     print('33[31;1m您输入的节点不存在!请重新输入!')
    188                     time.sleep(1)
    189 
    190         #######################2. 添加后端服务################################
    191         if select_num == '2':
    192             add_flag = True                                                   ###初始化添加循环标志###
    193             while add_flag:
    194                 backend_index =input('33[32;1m请输入添加的backend的编号或名称(返回上级菜单,请输入b):33[0m')
    195                 ##############################对输入值进行判断################
    196                 (backend_name,add_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
    197                 if backend_name:                                              ###显示对应backend下的server列表###
    198                     backend_server_show(backend_name,haproxy_server_show_dict)
    199                     add_server_dict = OrderedDict()                           ###设置实例默认为有序字典
    200                     print('33[34;1m请依次输入后端服务信息(name,address,weight,maxconn):33[0m')
    201                     add_server_dict['name'] = name_decide()                  ###对输入的name有效性进行判断###
    202                     add_server_dict['address'] = ipaddress_decide()          ###对输入的IP有效性进行判断###
    203                     add_server_dict['weight'] = number_decide('权重值')      ###对输入的权重有效性进行判断###
    204                     add_server_dict['maxconn'] = number_decide('最大连接数') ###对输入的连接数有效性进行判断###
    205 
    206                     print(add_server_dict['name'],add_server_dict['address'],add_server_dict['weight'],add_server_dict['maxconn'])
    207 
    208                     #############对输入的四个服务信息是否成功判断#############
    209                     if add_server_dict['name'] and add_server_dict['address'] and add_server_dict['weight'] and add_server_dict['maxconn']:
    210                         add_commit = input('33[31;1m请确认是否添加此条目(y | n):33[0m')
    211                         if add_commit == 'y':                                 ###确认添加服务条目,并回写配置文件###
    212                             haproxy_server_show_dict[backend_name].append(add_server_dict)
    213                             backend_server_handle(conf,haproxy_server_show_dict)
    214                         else:
    215                             add_flag = False                                  ###否则退出本次循环###
    216                     else:
    217                         print('33[1;31m server信息输入有误,请重新输入!!!33[0m')
    218                         time.sleep(2)
    219 
    220         #######################3. 修改后端服务#################################
    221         if select_num == '3':
    222             backend_modify_flag = True                                         ###初始化修改循环标志###
    223             while backend_modify_flag:
    224                 backend_index =input('33[32;1m请输入修改的backend的编号或名称(返回上级菜单,请输入b):33[0m')
    225                 ##############################对输入值进行判断################
    226                 (backend_name,backend_modify_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
    227 
    228                 if backend_name:                                               ###显示对应backend下的server列表###
    229                     backend_server_show(backend_name,haproxy_server_show_dict)
    230 
    231                     server_modify_flag = True                                  ###初始化server条目修改标志位###
    232                     while server_modify_flag:
    233 
    234                         server_index =input('33[32;1m请输入修改的server的编号(返回上级菜单,请输入b):33[0m')
    235                         if len(server_index) != 0:
    236                             server_index = input_handle(server_index)
    237                         if server_index == 'b':                               ###输入b,返还上一层###
    238                             server_modify_flag = False
    239                         #####################指定具体的server编号进行判断#####
    240                         elif server_index >= 1 and server_index <= len(haproxy_server_show_dict[backend_name]):
    241                             modify_server_dict = OrderedDict()
    242                             print('33[34;1m请依次输入后端服务信息(name,address,weight,maxconn):33[0m')
    243                             modify_server_dict['name'] = name_decide()        ###对输入的四个信息有效性进行判断###
    244                             modify_server_dict['address'] = ipaddress_decide()
    245                             modify_server_dict['weight'] = number_decide('权重值')
    246                             modify_server_dict['maxconn'] = number_decide('最大连接数')
    247 
    248                             print(modify_server_dict['name'],modify_server_dict['address'],modify_server_dict['weight'],modify_server_dict['maxconn'])
    249 
    250                             ######对输入的四个服务信息是否成功判断#############
    251                             if modify_server_dict['name'] and modify_server_dict['address'] and modify_server_dict['weight'] and modify_server_dict['maxconn']:
    252                                 modify_commit =input('33[32;1m请确认是否修改此条目(y|n):33[1m')
    253                                 if modify_commit == 'y':                      ###确认修改服务条目,并回写配置文件###
    254                                     haproxy_server_show_dict[backend_name][server_index - 1] = modify_server_dict
    255                                     backend_server_handle(conf,haproxy_server_show_dict)
    256                                     modify_server_flag = False
    257 
    258                                 else:                                         ###否则退出本次循环###
    259                                     modify_server_flag = False
    260                             else:
    261                                 print('33[31m server输入信息有误,请重新输入!!!33[0m')
    262                         else:
    263                             print('33[31m server编号输入错误,请重新输入!!!33[0m')
    264 
    265         #######################4. 删除后端服务################################
    266         if select_num == '4':
    267             backend_delete_flag = True                                        ###初始化删除循环标志###
    268             while backend_delete_flag:
    269                 backend_index =input('33[32;1m请输入删除的backend下条目编号或名称(返回上层菜单,请输入b):33[0m')
    270                 ##############################对输入值进行判断################
    271                 (backend_name,backend_delete_flag) = backend_input_if(backend_index,haproxy_name_show_dict)
    272 
    273                 if backend_name:                                              ###显示对应backend下的server列表###
    274                     backend_server_show(backend_name,haproxy_server_show_dict)
    275 
    276                     server_delete_flag = True                                 ###初始化server条目删除标志位###
    277                     while server_delete_flag:
    278 
    279                         server_index =input('33[32;1m请输入要删除的server编号(返回上层菜单,请输入b):33[0m')
    280                         if len(server_index) != 0:
    281                             server_index = input_handle(server_index)
    282                         if server_index == 'b':                               ###输入b,返还上一层###
    283                             server_delete_flag = False
    284                         #####################指定具体的server编号进行判断#####
    285                         elif server_index >= 1 and server_index <= len(haproxy_server_show_dict[backend_name]):
    286 
    287                             print(haproxy_server_show_dict[backend_name][server_index - 1])
    288                             delete_commit =input('请确认是否删除此条目(y|n):')
    289                             if delete_commit == 'y':                          ###确认删除服务条目,并回写配置文件###
    290                                 del haproxy_server_show_dict[backend_name][server_index - 1]
    291                                 backend_server_handle(conf,haproxy_server_show_dict)
    292                                 delete_server_flag = False
    293 
    294                             else:                                             ###否则退出本次循环###
    295                                 delete_server_flag = False
    296                         else:
    297                             print('33[31m server编号输入错误,请重新输入!!!33[0m')
    298 
    299         #######################5. 退出程序######################
    300         if select_num == '5':
    301            print('33[31;1m程序将在两秒后退出,欢迎再次使用,谢谢!33[0m')
    302            time.sleep(1)
    303            print('33[32;1m1s33[0m')
    304            time.sleep(1)
    305            print('33[32;1m2s33[0m')
    306            print('33[31;1m程序退出')
    307            sys.exit()
  • 相关阅读:
    UNIX 高手的另外 10 个习惯
    python中的cls到底指的是什么
    一篇文章搞懂Python装饰器所有用法
    sysbench 压测
    python面向对象进阶
    python 学生表
    搞懂蓝绿发布、灰度发布和滚动发布
    数据库之视图、索引
    Java内存模型(JMM)以及 垃圾回收机制 小结
    Java线程唤醒与阻塞
  • 原文地址:https://www.cnblogs.com/carl-angela/p/5430923.html
Copyright © 2020-2023  润新知