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('\n')
 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('\033[1m後端服務器(%s)信息以下:\033[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('\033[32;40m%-5s%20s%15s%25s\033[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('\033[32m請輸入新服務名(退出輸入q):\033[0m')
 59         if len(name_input) == 0:                                           ###若是輸入爲空則直接下一次循環###
 60             continue
 61         elif name_input == 'q':                                           ###輸入q,退出本次輸入###
 62             name_flag = False
 63             sys.exit('\033[32;1m腳本已退出!\033[1m')
 64         elif re.match('[0-9a-zA-Z\_]+',name_input):                       ###匹配輸入是否以字符、數字或下劃線開頭###
 65             name = name_input
 66             name_flag = False                                              ###輸入成功後退出循環###
 67         else:
 68             print('\033[31m名稱輸入錯誤,請從新輸入!!!\033[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('\033[32m請輸入新地址(IP哦)(退出輸入q):\033[0m')
 76         if len(address_input) == 0:                                        ###若是輸入爲空則直接下一次循環###
 77             continue
 78         elif address_input == 'q':                                        ###輸入q,退出本次輸入###
 79             address_flag = False
 80             sys.exit('\033[32;1m腳本已退出!\033[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('\033[31m地址輸入錯誤,請從新輸入!!!\033[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('\033[32m請輸入%s(數字哦)(退出輸入q):\033[0m' % name)
 94         if len(number_input) == 0:                                        ###若是輸入爲空則直接下一次循環###
 95             continue
 96         elif number_input == 'q':                                        ###輸入q,退出本次輸入###
 97             number_flag = False
 98             sys.exit('\033[32;1m腳本已退出!\033[32;1m')
 99         else:
100             try:
101                 int(number_input)                                         ###匹配輸入是不是數字###
102             except:
103                 print('\033[31;1m%s輸入類型錯誤,請從新輸入!!!\033[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 = '\tserver {name} {address} weight {weight} maxconn {maxconn}\n'
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('\033[33;1m server更新成功\033[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='\033[36m歡迎訪問haproxy配置文件管理腳本\033[0m'
157         print(hy.center(60,'*'))
158         print('\033[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         \033[35;1m1.查詢後端服務\033[0m
164         \033[35;1m 2.添加後端服務\033[0m
165         \033[35;1m 3.修改後端服務\033[0m
166         \033[31;1m 4.刪除後端服務\033[0m
167         \033[32;1m 5.退出\033[0m ''')
168         print(jgf.center(60,'='))
169         select_num = input('\033[35;1m請選擇操做條目:\033[0m')
170 
171         #######################1. 查詢後端服務################################
172         if select_num == '1':
173             query_flag = True                                                 ###初始化查詢循環標誌###
174             while query_flag:
175                 backend_index =input('\033[31;1m請輸入須要查詢的backend編號或名稱(返回上級菜單輸入b,退出輸入q):\033[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('\033[35;1m腳本退出!\033[0m')
185                 else:
186                     query_flag=False
187                     print('\033[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('\033[32;1m請輸入添加的backend的編號或名稱(返回上級菜單,請輸入b):\033[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('\033[34;1m請依次輸入後端服務信息(name,address,weight,maxconn):\033[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('\033[31;1m請確認是否添加此條目(y | n):\033[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('\033[1;31m server信息輸入有誤,請從新輸入!!!\033[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('\033[32;1m請輸入修改的backend的編號或名稱(返回上級菜單,請輸入b):\033[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('\033[32;1m請輸入修改的server的編號(返回上級菜單,請輸入b):\033[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('\033[34;1m請依次輸入後端服務信息(name,address,weight,maxconn):\033[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('\033[32;1m請確認是否修改此條目(y|n):\033[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('\033[31m server輸入信息有誤,請從新輸入!!!\033[0m')
262                         else:
263                             print('\033[31m server編號輸入錯誤,請從新輸入!!!\033[0m')
264 
265         #######################4. 刪除後端服務################################
266         if select_num == '4':
267             backend_delete_flag = True                                        ###初始化刪除循環標誌###
268             while backend_delete_flag:
269                 backend_index =input('\033[32;1m請輸入刪除的backend下條目編號或名稱(返回上層菜單,請輸入b):\033[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('\033[32;1m請輸入要刪除的server編號(返回上層菜單,請輸入b):\033[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('\033[31m server編號輸入錯誤,請從新輸入!!!\033[0m')
298 
299         #######################5. 退出程序######################
300         if select_num == '5':
301            print('\033[31;1m程序將在兩秒後退出,歡迎再次使用,謝謝!\033[0m')
302            time.sleep(1)
303            print('\033[32;1m1s\033[0m')
304            time.sleep(1)
305            print('\033[32;1m2s\033[0m')
306            print('\033[31;1m程序退出')
307            sys.exit()
相關文章
相關標籤/搜索