Python练习_更改配置文件(3)
学习完成第三阶段,我们来写一个功能:也就是实现对配置文件的backend字段进行增删改查
- 1、查
- 输入:www.oldboy.org
- 获取当前backend下的所有记录
- 2、新建
- 输入:
- arg = { 'bakend': 'www.oldboy.org', 'record':{ 'server': '100.1.7.9', 'weight': 20, 'maxconn': 30
- }
- }
- 3、删除
- 输入:
- arg = { 'bakend': 'www.oldboy.org', 'record':{ 'server': '100.1.7.9', 'weight': 20, 'maxconn': 30
- }
- }
需求
配置文件:
- global
- log 127.0.0.1 local2
- daemon
- maxconn 256
- log 127.0.0.1 local2 info
- defaults
- log global
- mode http
- timeout connect 5000ms
- timeout client 50000ms
- timeout server 50000ms
- option dontlognull
- listen stats :8888
- stats enable
- stats uri /admin
- stats auth admin:1234
- frontend oldboy.org
- bind 0.0.0.0:80
- option httplog
- option httpclose
- option forwardfor
- log global
- acl www hdr_reg(host) -i www.oldboy.org
- use_backend www.oldboy.org if www
- backend www.oldboy.org
- server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
配置文件
我的实现思路:
一、流程图:
二、功能实现思路
查询操作:
(1)首先捕获用户输入的域名,并定义一个空的列表用于存放查询域名下方的server内容,生成一个控制器flag = False
(2)开始打开配置文件并按行读取配置文件,开始按行循环判断,直到读取到当前行与用户输入匹配是,将flag变成=True这样就可以出发下面的代码,把server写入到列表中
(3)为了保证不输入多余的所以当匹配下一个以backend开头时将flag=False这样就不会触发下面的代码来写入了
(4)我将获取值得列表return了出来这样就可以使用ccc()自定义函数来格式化输出也可以判断当前域名是否查询到了结果
添加模块:
(1)使用循环可以让用户无需再次匹配关键字进入添加自定义函数中来添加
(2)首先设置几个全局列表用于保存backend信息,和server中的ip以及weight,maxconn的值因为这里可以循环添加所以一开始就将这几个列表清空保证正常添加
(3)首先判断用户输入的域名存在不存在,不存在直接在文件后面添加即可,存在则需要找到匹配的位置然后将所有server信息跟新添加的server信息加入到列表中,在写入,这里用到了老师的方法
(4) 因为使用了os.remove在windows下会出现问题,主要原因是文件以及存在所有我考虑到当添加的时候当前 file.bak文件也就是备份文件就没有必要存在所有我就先将他删除,在把file配置文件改成备份,
最后将新的文件改成配置文件的文件名这样就避免了windows下的错误
删除模块:
删除的原理跟添加差不多,考虑到有两种情况一种是删除整个域名的所有内容,还有的是删除域名下的server,对于整个域名来说只需要匹配成功的地方不写入新的配置文件就好了
至于删除server,只需要先将匹配项读出来写入列表然后,从列表中删除匹配删除的server项,在根据添加的模块进行写入就完成了
回滚功能:
存粹的更改文件名,没啥好说的
三、代码模块
代码:
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- import flow
- if __name__ == '__main__':
- print('''
- *******************************************************************************
- * -欢迎使用自动化修改工具- *
- * \033[31m !请谨慎修改!\033[0m *
- * *
- * F \033[35m<查询>\033[0m A \033[35m<添加>\033[0m D\033[35m <删除>\033[0m G\033[35m <滚回配置>\033[0m *
- * *
- *******************************************************************************
- ''')
- flow.log()
main主文件
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- def log():
- while True :#开始循环
- import func,time,os#加载func,函数全在里面
- times = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) #时间
- sssd = "请输入操作(exit结束)["+times+"]:"
- inpu = raw_input(sssd) #捕获操作
- if inpu == 'f': #f表示查询
- while True: #进入循环
- opp = raw_input('请输入查询域名(exit退出):')#获取用户要查询的域名
- if opp == 'exit': #如果为exit就退出
- break
- else: #否则进入查询模块
- sss = func.aaa(opp) #进入查询模块并,拿到查询模块的值
- aaa = len(sss) #判断返回值的列表是否为空
- if aaa > 0 : #如果不是空则输出结果
- print("\033[32m ----------------------- %s ---------------------\033[0m") %(opp)
- func.ccc(sss) #调用输出的函数
- print("\033[32m ---------------------------------------------------------\033[0m")
- break
- elif aaa == 0 : #如果是空则域名不存在
- print("您输入的域名不存在!")
- elif inpu == 'a' : #a表示添加
- func.add_log() #调用添加逻辑函数
- elif inpu == 'd':
- func.rem()
- elif inpu == 'g':
- func.rest()
- elif inpu == 'exit':
- os._exit(0)
逻辑文件flow
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- import os
- #查找内容
- backend_new = []#存放主机名称的列表
- backend_newip = []#存放ip跟weight,maxconn的列表 用于后面的写入
- backend_ser = []
- #查询模块
- def aaa(app):
- pap_list1 = []#定义一个空列表用于存放查询的结果
- pap_title = 'backend %s' %(app) #传入flow的opp的值
- with open('file') as pen: #打开文件
- flag = False #flag等于假
- for lin in pen: #从pen按行读出
- lin = lin.strip() #去除空
- if lin == pap_title: #判断lin的内容跟pap_title的内容是否相同,因为我们要拿取backend加域名下面的地址地址地址地址
- flag = True #将flag=真,这样就可以激活下面两个判断
- continue #并且当前循环结束
- elif flag and lin.startswith('backend'):#这里flag为真,但是还有一个条件也就是碰到下一个backend的时候,出发下面的代码
- flag = False #将flag设置为false,并且退出循环,因为我们拿到我们需要的结果了
- break
- elif flag : #flag为真出发下面
- pap_list1.append(lin) #将此时的lin 写入pap_list1列表中
- return pap_list1 #将列表的值传出
- #排序输出
- def ccc(aad): #利用循环格式化输出
- q = 1
- ss = ' [{aa}]_____({bb})'
- for i in aad:
- ss.format(aa=q,bb=i)
- print(ss.format(aa=q,bb=i))
- q = q + 1
- #生成域名列表用于,判断
- def ddd():
- pad_list1 = [] #生成空列表
- with open('file') as ped: #打开文件
- for lid in ped: #for循环读取文件
- if lid.startswith('backend'): #碰到以backend开头的写入pad_list1列表
- pad_list1.append(lid)
- return pad_list1 #将 pad_list1 传出
- #验证ip模块,判断用户输入ip是否正确
- #用于判断id,这里写的不好等学会re进行更改
- def ip():
- ser_1 = raw_input("请输入主机1的ip地址:")#获取第一个ip
- ser_2 = raw_input("请输入主机2的ip地址:")#获取第二个ip
- ser1_list = ser_1.strip().split('.') #以·进行分割
- ser2_list = ser_2.strip().split('.') #同理
- ser1_list.extend(ser2_list) #将两个列表合成
- ser1_list = set(ser1_list) #去除相同的
- for ser in ser1_list: #开始循环取值
- q_2 = str.isdigit(ser) #判断值是不是数字
- if q_2 == True:#如果是进入循环
- sea = int(ser)#转换成int类型
- if sea < 255 : #比较是否小于255
- seradd = True #如果小于则 seradd等于True
- backend_newip.append(ser_1) #列表 backend_newip 传入值
- backend_newip.append(ser_2)#列表 backend_newip 传入值
- wm() #运行wm函数
- break #退出循环
- else: #否则
- seradd = False#seradd= False
- break #退出循环
- else:#如果不是则直接推出,并返回值seradd = False,我用这个激活别的代码
- print("--------------------\033[32m↓↓↓您输入的ip有误↓↓↓\033[0m--------------------")
- seradd = False
- break
- return seradd
- #weight和maxconn
- def wm(): #获取weight和maxconn的值
- while True:
- sew_1 = raw_input("请输入weight的值:")
- sew_2 = raw_input("请输入maxconn的值:")
- if str.isdigit(sew_1) and str.isdigit(sew_2): #判断类型是不是数字
- backend_newip.append(sew_1) #是的话则写入
- backend_newip.append(sew_2)
- print(backend_newip)
- print("ok")
- break #退出循环
- else: #不是的话则重新输入
- print("-------------------\033[32m↓↓↓您输入有误↓↓↓\033[0m-------------------")
- #添加模块
- def add_log():
- while True:#进行添加循环
- inp_d = raw_input('请输入添加的域名(exit退出):') #添加的域名
- del backend_newip[:]#第二次添加时清空列表
- del backend_ser[:]#第二次添加时清空列表
- del backend_new[:]#第二次添加时清空列表
- paa_title = 'backend %s\n' %(inp_d) #用于判断
- ddd() #执行函数
- rec_a = ddd() #得到文件中所有域名的类别
- if paa_title in rec_a: #查看用户输入是否包含在当前文件中
- inp_d1 = raw_input('当前域名已存在是否添加记录(y/n):') #如果包含,请用户判断是否添加记录
- if inp_d1 == 'y':
- backend_new.append(inp_d)
- ip_result = ip()
- print ip_result
- if ip_result == True: #如果上面执行的结果为真那么就进行添加
- aasd = aaa(inp_d)
- for add_l in aasd:
- backend_ser.append(add_l)
- asp()
- elif inp_d1 == 'n': #如果等于n 则退出
- print("-------------------\033[32m已经退出\033[0m-------------------")
- break
- elif inp_d == 'exit': #等于exit则退出
- print("-------------------\033[32m→已退出←\033[0m-------------------")
- break
- elif inp_d.count('.') != 2: #判断输入是否有两个 点 判断输入的类型,如果没有则提示错误
- print("-------------------\033[32m↓↓↓您输入的域名有误↓↓↓\033[0m-------------------")
- elif inp_d.count('.') == 2: #如果有两个点则进行添加,因为第一个if判断是否在文件中,所以处理到这里当前域名肯定不在文件中
- inp_d2 = raw_input("您正在添加新的域名是否继续(y/n):") #判断是是否添加
- if inp_d2 == 'y': #如果是y则执行添加
- backend_new.append(inp_d) #将域名传入保存域名的列表
- ip_result = ip() #执行ip函数并得到结果
- print(backend_new) #打印结果
- print ip_result #打印列表,包含ip等信息
- if ip_result == True: #如果上面执行的结果为真那么就进行添加
- asd() #添加模块
- elif inp_d2 == 'n': #如果等于n 则退出
- print("-------------------\033[32m已经退出\033[0m-------------------")
- break
- #在末尾写入文件模块
- def asd():
- with open('file') as file_open,open('file_new','w') as new_open:#同时打开两个文件
- back_ls = "backend %s\n" %(backend_new[0]) #生成backend条码
- back_ls1 = " server %s %s weight %s maxconn %s\n" %(backend_newip[0],backend_newip[1],backend_newip[2],backend_newip[3])#生成server条目
- print('您要添加的域名:\033[32m%s\033[0m,添加的server1:\033[32m%s\033[0m,添加的server2:\033[32m%s\033[0m,添加的weighe:\033[32m%s\033[0m,添加的maxconn:\033[32m%s\033[0m') %(backend_new[0],backend_newip[0],backend_newip[1],backend_newip[2],backend_newip[3])
- for a_new in file_open: #把老文件前内容都写入新文件中
- new_open.write(a_new)
- new_open.write(back_ls) #然后写入backend 语句
- new_open.write(back_ls1) #写入server语句
- print("ok") #输出
- os.remove("file.bak")
- os.rename('file','file.bak')
- os.rename('file_new','file')
- #传入域名存在的配置
- def asp():
- asp_a = True #设定asp_a 等于True 这样就可以激活elif asp_a 从而执行添加
- paa_title = 'backend %s\n' %(backend_new[0]) #生成用户输入的backend条目
- asp_ls = "server %s %s weight %s maxconn %s" %(backend_newip[0],backend_newip[1],backend_newip[2],backend_newip[3])#生成server条目
- print('您要添加的域名:\033[32m%s\033[0m,添加的server1:\033[32m%s\033[0m,添加的server2:\033[32m%s\033[0m,添加的weighe:\033[32m%s\033[0m,添加的maxconn:\033[32m%s\033[0m') %(backend_new[0],backend_newip[0],backend_newip[1],backend_newip[2],backend_newip[3])
- #上面一句是提示打印
- backend_ser.append(asp_ls) #将新的server条目跟原来的server条目进行合成
- with open('file') as file_open,open('file_new','w') as new_open: #打开两个文件
- for sp_up in file_open: #循环读取file的内容
- if sp_up == paa_title: #如果sp_up的内容等于用户输入的内容就将这行添加到file_new中,并且开始循环server的列表进行添加
- print("正常")
- new_open.write(sp_up)
- for as_2 in backend_ser:
- aaa = ' '*8+as_2+'\n'
- new_open.write(aaa)
- asp_a = False #为了不让最后一个elif继续添加这里进行false 停止
- continue #并且结束当前循环,为了不触发下面的条目将asp_a变回True
- elif sp_up.startswith('backend'): #因为上面输入了匹配backend条目的server所以直到碰到下一个backend才开始输入
- new_open.write(sp_up) #输入backend,因为if判断将这个条目进入到这里这里不会去匹配下一个条件所以这里要添加进去
- asp_a = True #并将asp_a变成True这样就重新激活了下面的elif,通过下面将剩下的文件写入
- elif asp_a:
- new_open.write(sp_up)
- os.remove("file.bak")
- os.rename('file','file.bak') #换名
- os.rename('file_new','file') #换名
- #删除逻辑处理
- def rem():
- while True:
- del backend_ser[:]#第二次添加时清空列表
- del backend_new[:]#第二次添加时清空列表
- re_in = raw_input("请输入你要删除的域名(exit退出):")
- re_inup = "backend %s\n" %(re_in)
- re_up = ddd()
- if re_in == "exit":
- break
- re_ins = raw_input("是否要删除\033[31m整个域名条目\033[0m(y/n)")
- if re_ins == "y":
- if re_inup in re_up:
- backend_new.append(re_in)
- delta()
- elif re_ins == "n":
- if re_inup in re_up:
- backend_new.append(re_in)
- re_up2 = aaa(re_in)
- for isd in re_up2:
- backend_ser.append(isd)
- print("\033[32m ----------------------- %s ---------------------\033[0m") %(re_in)
- ccc(re_up2)
- print("\033[32m ---------------------------------------------------------\033[0m")
- while True:
- re_ser = raw_input("请输入你要删除的server第一个ip地址(exit退出):")
- re_str = "server %s" %(re_ser)
- if re_ser == "exit" :
- break
- elif re_ser.count('.') == 3:
- for re_ups in re_up2:
- if re_ups.startswith(re_str):
- print('ok')
- print("您要删除的条目:%s") %(re_ups)
- backend_ser.remove(re_ups)
- delt()
- break
- else:
- print("!!!输入有误!!!")
- else:
- print("------------\033>>>>>[32m当前域名不存在\033[0m------------")
- #删除server功能函数
- def delt():
- asp_a = True #设定asp_a 等于True 这样就可以激活elif asp_a 从而执行添加
- paa_title = 'backend %s\n' %(backend_new[0]) #生成用户输入的backend条目
- with open('file') as file_open,open('file_new','w') as new_open: #打开两个文件
- for sp_up in file_open: #循环读取file的内容
- if sp_up == paa_title: #如果sp_up的内容等于用户输入的内容就将这行添加到file_new中,并且开始循环server的列表进行添加
- new_open.write(sp_up)
- for as_2 in backend_ser:
- aaa = ' '*8+as_2+'\n'
- new_open.write(aaa)
- asp_a = False #为了不让最后一个elif继续添加这里进行false 停止
- continue #并且结束当前循环,为了不触发下面的条目将asp_a变回True
- elif sp_up.startswith('backend'): #因为上面输入了匹配backend条目的server所以直到碰到下一个backend才开始输入
- new_open.write(sp_up) #输入backend,因为if判断将这个条目进入到这里这里不会去匹配下一个条件所以这里要添加进去
- asp_a = True #并将asp_a变成True这样就重新激活了下面的elif,通过下面将剩下的文件写入
- elif asp_a:
- new_open.write(sp_up)
- os.remove("file.bak")
- os.rename('file','file.bak') #换名
- os.rename('file_new','file') #换名
- print("------------\033>>>>>[32m配置文件替换完成<<<<<\033[0m------------")
- #删除域名功能函数,实现方法很简单只需要匹配到相关项不添加即可
- def delta():
- asp_a = True #设定asp_a 等于True 这样就可以激活elif asp_a 从而执行添加
- paa_title = 'backend %s\n' %(backend_new[0]) #生成用户输入的backend条目
- with open('file') as file_open,open('file_new','w') as new_open: #打开两个文件
- for sp_up in file_open: #循环读取file的内容
- if sp_up == paa_title: #如果sp_up的内容等于用户输入的内容就将这行添加到file_new中,并且开始循环server的列表进行添加
- asp_a = False #为了不让最后一个elif继续添加这里进行false 停止
- continue #并且结束当前循环,为了不触发下面的条目将asp_a变回True
- elif sp_up.startswith('backend'): #因为上面输入了匹配backend条目的server所以直到碰到下一个backend才开始输入
- new_open.write(sp_up) #输入backend,因为if判断将这个条目进入到这里这里不会去匹配下一个条件所以这里要添加进去
- asp_a = True #并将asp_a变成True这样就重新激活了下面的elif,通过下面将剩下的文件写入
- elif asp_a:
- new_open.write(sp_up)
- os.remove("file.bak")
- os.rename('file','file.bak') #换名
- os.rename('file_new','file') #换名
- print("配置文件替换完成")
- #还原最近一次配置
- def rest():
- ress = raw_input("请谨慎操是否回滚到最近一次配置(y):")
- if ress == "y" :
- os.rename("file","back")
- os.rename('file.bak','file')
- os.rename("back","file.bak")
- else:
- print("------------\033[32m>>>>>退出还原配置<<<<<\033[0m------------")
函数文件func
两个配置文件:
- frontend oldboy.org
- bind 0.0.0.0:80
- option httplog
- option httpclose
- option forwardfor
- log global
- acl www hdr_reg(host) -i www.oldboy.org
- use_backend www.oldboy.org if www
- backend www.aaa.com
- server 100.1.2.9 100.1.5.9 weight 20 maxconn 3000
- server 100.1.3.9 100.1.6.9 weight 20 maxconn 3000
- backend www.bbb.com
- server 100.2.1.9 100.2.3.9 weight 20 maxconn 3000
- server 100.2.2.9 100.2.4.9 weight 20 maxconn 3000
- backend www.ccc.com
- server 100.3.2.9 100.3.4.9 weight 50 maxconn 50
file文件
- frontend oldboy.org
- bind 0.0.0.0:80
- option httplog
- option httpclose
- option forwardfor
- log global
- acl www hdr_reg(host) -i www.oldboy.org
- use_backend www.oldboy.org if www
- backend www.aaa.com
- server 100.1.2.9 100.1.5.9 weight 20 maxconn 3000
- server 100.1.3.9 100.1.6.9 weight 20 maxconn 3000
- server 1.1.1.1 2.2.2.2 weight 20 maxconn 20
- backend www.bbb.com
- server 100.2.1.9 100.2.3.9 weight 20 maxconn 3000
- server 100.2.2.9 100.2.4.9 weight 20 maxconn 3000
- backend www.ccc.com
- server 100.3.2.9 100.3.4.9 weight 50 maxconn 50
file.bak
Python练习_更改配置文件(3)的更多相关文章
- python练习_简单登录
python练习_简单登录 需求: 做一个登录的小程序,验证用户与密码 要求登录三次错误后锁定 以下代码实现的功能与思路: 功能: 1.除admin以外的用户累计登录失败次数超过三次则锁定,此时需要管 ...
- python开发_++i,i += 1的区分
python开发_++i,i += 1的区分 在很多编程语言(C/C++,Java等)中我们都会碰到这样的语法: 1 int i = 0; 2 ++ i; // -- i; 这样的语法在上述编程语言中 ...
- python学习_数据处理编程实例(二)
在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...
- python练习_购物车(简版)
python练习_购物车(简版) 需求: 写一个python购物车可以输入用户初始化金额 可以打印商品,且用户输入编号,即可购买商品 购物时计算用户余额,是否可以购买物品 退出结算时打印购物小票 以下 ...
- Python中操作ini配置文件
这篇博客我主要想总结一下python中的ini文件的使用,最近在写python操作mysql数据库,那么作为测试人员测试的环境包括(测试环境,UAT环境,生产环境)每次需要连接数据库的ip,端口,都会 ...
- Python递归_打印节点信息
Python递归_打印节点信息 递归特性:1.必须由一个明确的结束条件2.每次进入更深一层递归时,问题规模相比上一次递归都应该有所减少3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用时 ...
- 通过python生成nginx模板配置文件
通过python生成nginx模板配置文件 # cat config.py #coding=utf-8 nginx_conf = ''' server {{ listen {port}; server ...
- python创建目录并更改权限的代码
如下代码段是关于python创建目录并更改权限的代码. import os os.mkdir("foo", 0666)
- python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学
首发于:python人工智能爬虫系列:怎么查看python版本_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=431 本文 ...
随机推荐
- [转载]浅析Windows安全相关的一些概念
Session 我们平常所说的Session是指一次终端登录, 这里的终端登录是指要有自己的显示器和鼠标键盘等, 它包括本地登录和远程登录.在XP时代每次终端登录才会创建一个Session,但是在Vi ...
- javascript中base64和Gzip的使用
一般的使用流程(4步): 服务器端将字符串Gzip压缩为 字节数组——>通过base64转为字符串(后传递到客户端)——>解码base64字符串为字节数组——>Gzip解码字节数组为 ...
- PPT 制作必备工具
1.图标 http://www.easyicon.net/ http://ico.58pic.com/ http://www.iconpng.com/ 2.字体 http://www.qiuziti. ...
- IE6、7 a链接内图片加滤镜后导致a标签链接失效问题解决
今天在项目中遇到一个ie6.7浏览器下a链接失效的问题,查询大量资料,最终找到完美的解决方案,如下: 解决方法: 为a标签加样式{*background:url(#);*zoom:1;} 为img外部 ...
- Android studio 配置JNI环境
Android studio配置jni开发环境,主要配置是两个build文件,以及新建一个jni文件,放c代码. 代码如下1: apply plugin: 'com.android.model.app ...
- Python闭包及装饰器
Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...
- entity framework如何控制并发
entity framework如何控制并发 针对字段http://msdn.microsoft.com/en-us/library/vstudio/bb738618(v=vs.100).aspx ...
- svn unable to connect to a repository at url 执行上下文错误 不能访问SVN服务器问题
1.检查visual SVN server 本地仓库服务是否正常启动 如果是SVN server service的的问题情形: (1).使用browser打开仓库位置,结果连接打不开. (2).查看s ...
- linux命令之mount
熟悉linux的同学都应该知道mount命令.在linux中,一切皆文件.硬盘分区都是以文件目录的方式存在. 如果我们想访问移动硬盘,U盘等我们必须将这些设备mount到我们linux文件系统中某个目 ...
- JSPatch 动态更新,bug修复
本文贴出项目中热修复的代码片段: require('UIView, JPObject, HtmlAllViewController,DataManager,EMClient,EaseMessageVi ...