#!/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 == '':
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 == '':
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 == '':
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 == '':
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 == '':
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()

Python-day3作业-haproxy配置文件管理脚本的更多相关文章

  1. Haproxy安装部署文档及多配置文件管理方案

    一.部署安装 二.软件配置 三.系统服务 四.日志配置 五.小结 文章目录 最近我在负责一个统一接入层的建设项目,涉及到 Haproxy 和 ospf 的运维部署,本文分享一下我在部署 Haproxy ...

  2. Linux安装LAMP开发环境及配置文件管理

    Linux主要分为两大系发行版,分别是RedHat和Debian,lamp环境的安装和配置也会有所不同,所以分别以CentOS 7.1和Ubuntu 14.04做为主机(L) Linux下安装软件,最 ...

  3. Selenium-RC Python 2.7 环境配置

    1.下载并安装Python http://www.python.org/getit/,我使用的是2.7.3的python版本 2.下载并安装setuptools[这个工具是python的基础包工具] ...

  4. Spark配置&启动脚本分析

    本文档基于Spark2.0,对spark启动脚本进行分析. date:2016/8/3 author:wangxl Spark配置&启动脚本分析 我们主要关注3类文件,配置文件,启动脚本文件以 ...

  5. haproxy配置基于ssl证书的https负载均衡

    本实验全部在haproxy1.5.19版本进行测试通过,经过测试1.7.X及haproxy1.3版本以下haproxy配置参数可能不适用,需要注意版本号. 一.业务要求现在根据业务的实际需要,有以下几 ...

  6. python的开发环境配置-Eclipse-PyDev插件安装

    安装PyDev插件的两种安装方法: 1.百度搜索PyDev 2.4.0.zip,下载后解压,得到Plugins和Feature文件夹,复制两文件夹到Eclipse目录,覆盖即可. 插件的版本要对应py ...

  7. 怎么样通过编写Python小程序来统计测试脚本的关键字

    怎么样通过编写Python小程序来统计测试脚本的关键字 通常自动化测试项目到了一定的程序,编写的测试代码自然就会很多,如果很早已经编写的测试脚本现在某些基础函数.业务函数需要修改,那么势必要找出那些引 ...

  8. 死磕salt系列-salt 配置文件管理

    SLS是Salt State系统的核心,用来描述系统的目标状态,使用YAML语言书写.被用作配置文件管理. SLS文件 sls配置文件分为两种类型 top.sls 这是所有配置文件的入口 sls 这是 ...

  9. 基于七牛Python SDK写的一个同步脚本

    需求背景 最近刚搭了个markdown静态博客,想把博客的图片放到云存储中. 经过调研觉得七牛可以满足我个人的需求,就选它了. 博客要引用图片就要先将图片上传到云上. 虽然七牛网站后台可以上传文件,但 ...

随机推荐

  1. SAP SD 销售凭证如何设置字段必填

    在实际业务中,我们经常遇到需要设置某些字段是必输的.那么在SAP中创建销售订单时如何控制必填字段呢?请看操作手册 第一步:设置屏幕增强 T-CODE:shd0 上截图 1----输入需要控制的事物代码 ...

  2. 学习winform第三方界面weiFenLuo.winFormsUI.Docking.dll

    控件dockpanel中提供了几个可用的类, 重要的有两个, 一是DockPanel, 一是DockContent, DockPanel是从panel继承出来的, 用于提供可浮动的dock的子窗口进行 ...

  3. iOS 开发之控件快速学习(一)

    最近一个朋友想转iOS所以我开始写一些初级iOS学习博客!也希望第一些初学的朋友有所帮助,!好吧进入今天的正题,我们今天主要完成如下界面的显示! 好的一起打开Xcode一下几步我截图说明:

  4. python datetime处理时间

    原文:http://blog.csdn.net/JGood/article/details/5457284 Python提供了多个内置模块用于操作日期时间,像calendar,time,datetim ...

  5. Visual Basic 2012 借助DataGridView控件将SQL server2012 数据导入到Excel 2010

    摘  要: SQL Server 2012 数据和Excel 2010之间的连接和数据的传输,本篇文章主要针对的是SQL Server 2012 数据导入到Excel 2010文件中.Excel软件对 ...

  6. tab事件优化-事件代理

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 对于Python中self的看法

    首先看一段Java代码 public class Test { public String name; public int age; public String gender; public Str ...

  8. Swift 2.0 异常处理

    转自:http://www.jianshu.com/p/96a7db3fde00 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主 ...

  9. Android开发-动态布局小记

    android动态布局相比静态布局,动态布局不用再将xml转变了布局代码,提高了一定的效率,当然可以忽略不记.动态布局主要是比较灵活,可以很快的在代码中直接修改布局,并直接使用控件进行业务逻辑开发.但 ...

  10. Ajax 语法

    /*** * ajax语法 * * ***/ $.ajax({ async:false, //同步请求 url:"XXXXX.do",//请求后台地址 data: {"p ...