python操作文件练习,配置haproxy
在使用python操作文件的时候,特别是对于网络设备,通常操作配置文件,会简化配置量,配置文件加载到内存中,运行时使用的是内存中的配置,内存中配置修改后立即生效,如果不将配置内容保存到硬盘中,则下次重新启动会导致配置丢失。下面模拟一下haproxy的backend的添加删除修改。
示例的配置文件如下:
global
log 127.0.0.1 local2
daemon
maxconn
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 :
stats enable
stats uri /admin
stats auth admin: frontend cccc.org
bind 0.0.0.0:
option httplog
option httpclose
option forwardfor
log global
acl www hdr_reg(host) -i www. cccc.org
use_backend www. cccc.org if www backend www. cccc.org
server 100.1.7.9 100.1.7.9 weight maxconn
server 100.1.7.8 100.1.7.8 weight maxconn
server 100.1.7.7 100.1.7.7 weight maxconn
backend www.cccc.com
server server110 192.168.1.110 weight maxconn
需求如下:
1、当输入backend的名字时,要求能打印出属于该backend的所有server信息,格式化输出
2、可以添加backend的server,输入相关属性字段后,完成添加
3、可以删除backend的server信息。
4、以上要求,要基于python 的文件操作来实现。
想了好久之后,有以下几个点是需要注意的地方:
1、配置文件是存放在硬盘中的,硬盘上的数据不能直接在中间插入修改,只能先将内容读取到内存中,在内存中进行修改
2、主要修改的地方backend字段,backend字段在整个配置文件中的是有顺序的,修改了前后的内容,都需要在对应的位置上
3、backend下可能存在多个server,每个server都有固定的属性配置,可能存在多个backend
下面简单写了一个操作的方法。
#!/usr/bin/env python
#-*- coding:utf-8 -*- def get_configuration(configuration_name):
configuration = open(configuration_name,"r",encoding="utf-8")
configuration_dict = {}
configuration_full = []#定义一个列表,用来存放所有的配置信息
line_number = 0#定义一个计数器,用来记录关键位置的信息,比如backend开始时候的数字信息,在列表中的位置
configuration_position = []#定义一个列表,用来存放出现的backend的位置
for line in configuration:
# line = line.strip()#清除前后的空格
backend_server_configuration_all =[]
if line.strip().startswith("backend"):#如果开头是backend,证明后面是一个节点域名信息。记录第一个出现的行数信息
backend_position = line_number
line_list = line.strip().split(" ")
backend_name = line_list[1]
configuration_dict[backend_name] = []
configuration_position.append(line_number)#如果出现backend,记录出现的位置,到时候好用来恢复文件的位置。
elif line.strip().startswith("server"):
line_list = line.strip().split(" ")
server_name = line_list[1]
server_address = line_list[2]
server_weight = line_list[4]
server_maxconn = line_list[6]
backend_server_configuration = {"server_name":server_name,
"server_address":server_address,
"server_weight":server_weight,
"server_maxconn":server_maxconn}
configuration_dict[backend_name].append(backend_server_configuration)#列表增加一个配置项
else:
configuration_full.append(line)
line_number += 1
# print(line_number)
# print(configuration_position)
#将配置字典,完整的配置信息,和配置点的信息返回,完整配置信息中不包含配置字典信息
return configuration_dict,configuration_full,configuration_position #查询是否存在对应的backend,如果有,将server信息打印
def select_backend(configuration_dict):
backend_name = input("请输入要查询的backend名称:")
if backend_name in configuration_dict.keys():
backend_server_list = configuration_dict[backend_name]
print("backend :%s"%backend_name)
for backend_server_item in backend_server_list:
print_backend(backend_server_item)
else:
print("输入的backend不存在") #打印,格式化打印
def print_backend(backend_server_item):
print(
'''--------------------------
server_name:%s
server_address:%s
server_weight:%s
server_maxconn:%s'''%(backend_server_item["server_name"],backend_server_item["server_address"],backend_server_item["server_weight"],backend_server_item["server_maxconn"])) def configuration_input():#获取需要操作的对象信息
backend_name = input("backend name:")
server_name = input("server name:")
server_address = input("server address:")
server_weight = input("server weight:")
server_maxconn = input("server weight:")
return backend_name,server_name,server_address,server_weight,server_maxconn #增加节点
def add_backend(configuration_dict):
#获取当前配置文件的完整配置信息
#将添加节点的关键信息,整理成字典,如果该节点所属的名字在配置中存在,则追加新的配置项,如果不存在,则直接添加
configuration_new = configuration_input()
backend_name = configuration_new[0]
server_name = configuration_new[1]
server_address = configuration_new[2]
server_weight = configuration_new[3]
server_maxconn = configuration_new[4]
backend_server_configuration = {"server_name": server_name,
"server_address": server_address,
"server_weight": server_weight,
"server_maxconn": server_maxconn}
if backend_name in configuration_dict.keys():
configuration_dict[backend_name].append(backend_server_configuration)
else:
configuration_dict[backend_name] = [backend_server_configuration]
print("添加成功!")
return configuration_dict
#删除后台节点,返回字典文件
def delete_backend(configuration_dict):
configuration_new = configuration_input()
backend_name = configuration_new[0]
server_name = configuration_new[1]
server_address = configuration_new[2]
server_weight = configuration_new[2]
server_maxconn = configuration_new[4]
if backend_name in configuration_dict:
backend_server_configuration = {"server_name": server_name,
"server_address": server_address,
"server_weight": server_weight,
"server_maxconn": server_maxconn}
# for backend_server in configuration_dict[backend_name]:
if backend_server_configuration in configuration_dict[backend_name]:
configuration_dict[backend_name].remove(backend_server_configuration)
if configuration_dict[backend_name] == []:#如果配置中该节点下没有了后台站点,就把该配置项删除。
configuration_dict.pop(backend_name)
print("删除成功!")
else:
print("删除的backend不存在,请检查输入")
return configuration_dict def show_backend(configuration_dict):
for backend_name in configuration_dict.keys():
backend_server_list = configuration_dict[backend_name]
print("********************************")
print("backend :%s"%backend_name)
for backend_server_item in backend_server_list:
print_backend(backend_server_item)
print("********************************") #定义写文件的函数,将配置脚本传递进去,然后写入到某个文件中,如果配置中有其他配置,需要将配置内容插入到原配置内容的位置
def new_configuration(configuration_dict,configuration_full,configuration_position):
# configuration_new = open(configuration_name,'w',encoding='utf-8')
# configuration_full = get_configuration(configuration_name)[1]
# configuration_position = get_configuration(configuration_name)[2][0]#只取出第一个位置点,然后以该位置为基础,往后排
configuration = configuration_dict
# print(configuration)
# for item in configuration:
backend_servers = []
backend_server = []
for key in configuration:#取出backend的名字,以该名字为键,值是后端服务器列表
backend_name = key
backend_string = "backend %s\n"%backend_name
backend_server.append(backend_string)
for server_item in configuration[key]:
server_string = '''\t\tserver %s %s weight %s maxconn %s\n'''%(server_item["server_name"],server_item["server_address"],server_item["server_weight"],server_item["server_maxconn"])#格式化写入文件的内容,前后是可以用tab,中间必须是空格,因为在拆分的时候使用的空格,split
backend_server.append(server_string)#将同一个backend的后端多台服务器,放在同一个列表中
# print(backend_server)
position_tmp = 0
#将拿到的配置列表,写入到之前拿到的配置信息列表中,定向插入到之前的位置
while position_tmp < len(backend_server):
new_position = configuration_position + position_tmp
configuration_full.insert(new_position,backend_server[position_tmp])
position_tmp += 1
# print(configuration_full)
return configuration_full #返回整体的配置信息 #定义写文件的方法,将配置文件整体写入到文件中
def write_configuration(configuration_name,configuration_full):
configuration_new = open(configuration_name, 'w', encoding='utf-8')
for line in configuration_full:
configuration_new.write(line)
configuration_new.close() # string_format = '''--------------------------
# server_name:%s
# server_address:%s
# server_weight:%s
# server_maxconn:%s'''%(1,2,3,4)
# # print(string_format)
#查询
# select_backend("haproxy_configuration",'www.oldboy.org')
# configuration_dict = add_backend("111","www.cmcc.com",'server108','192.168.200.108',30,5000)
# configuration_dict = add_backend("haproxy_configuration","www.cmcc.com",'server108','192.168.200.108',30,5000)
# configuration_dict = delete_backend("haproxy_configuration","www.cmcc.com",'server108','192.168.200.108','30','5000')
# show_backend(configuration_dict)p # select_backend(configuration_dict,'www.cmcc.com')
# configuration_dict = get_configuration("haproxy_configuration")
# configuration_full = new_configuration(configuration_dict,'haproxy_configuration')
# write_configuration('haproxy_configuration',configuration_full)
if __name__ == '__main__':
configuration_name = "haproxy_configuration"
configuration_tuple = get_configuration(configuration_name)
configuration_dict = configuration_tuple[0]
configuration_full = configuration_tuple[1]
configuration_position = configuration_tuple[2][0]
option_list = ['查询','显示所有','增加backend','删除','保存退出']
exit_flag = True
while exit_flag: for No,option in enumerate(option_list,1):
print("%d:%s"%(No,option))
user_select = input("请输入操作的编号:")
# user_select = int(user_select)
if user_select == "":
select_backend(configuration_dict)
elif user_select == "":
show_backend(configuration_dict)
elif user_select == "":
configuration_dict = add_backend(configuration_dict)
elif user_select == "":
configuration_dict = delete_backend(configuration_dict)
elif user_select == "":
configuration_full = new_configuration(configuration_dict,configuration_full,configuration_position)
write_configuration(configuration_name,configuration_full)
exit_flag = False
else:
print("输入错误,请重新输入。")
用到的主要方法还是文件的操作、字符串的操作、字典和列表的嵌套、循环。所有的方法之间,调用的输入参数和输出参数,都设置固定的格式字典,基于字典进行相关操作。最后能够实现全部查询、指定查询、删除、添加、保存退出。最后体现在文件上。
python操作文件练习,配置haproxy的更多相关文章
- Python操作文件、文件夹、字符串
Python 字符串操作 去空格及特殊符号 s.strip().lstrip().rstrip(',') 复制字符串 #strcpy(sStr1,sStr2) sStr1 = 'strcpy' sSt ...
- Python操作文件和目录
Python操作文件和目录 读写文件比较简单,有一点特别注意就好了 windows下Python默认打开的文件以gbk解码,而一般我们的文件是utf-8编码的,所以如果文本含有中文,就会出现异常或者乱 ...
- Python操作文件-20181121
Python操作文件 Python操作文件和其他语言一样,操作的过程无非是先定位找到文件.打开文件,然后对文件进行操作,操作完成后关闭文件即可. 文件操作方式:对文件进行操作,主要就是读.写的方式,p ...
- 使用python操作文件实现购物车程序
使用python操作文件实现购物车程序 题目要求如下: 实现思路 始终维护一张字典,该字典里保存有用户账号密码,购物车记录等信息.在程序开始的时候读进来,程序结束的时候写回文件里去.在登录注册的部分, ...
- 用Python操作文件
用Python操作文件 用word操作一个文件的流程如下: 1.找到文件,双击打开. 2.读或修改. 3.保存&关闭. 用Python操作文件也差不多: f=open(filename) # ...
- python操作文件案例二则
前言 python 对于文件及文件夹的操作. 涉及到 遍历文件夹下所有文件 ,文件的读写和操作 等等. 代码一 作用:查找文件夹下(包括子文件夹)下所有文件的名字,找出 名字中含有中文或者空格的文件 ...
- open -python操作文件
一打开文件 二操作文件 三关闭文件 open(文件,模式,编码),打开文件----->0101010(以二进制的方式打开)------>编码(open默认utf-8编码)------> ...
- Python操作文件文档
需要帮老师将44G的图书分类一下,人工当然累死了.所以用Python大法处理一下. 思路是读取文件目录下的书名,然后去百度百科查分类,如果还没有就去豆瓣,当当查.哪一个先找到其余的就不用找了.如果没有 ...
- Python 操作文件、文件夹、目录大全
# -*- coding: utf-8 -*- import os import shutil # 一. 路径操作:判断.获取和删除 #1. 得到当前工作目录,即当前Python脚本工作的目录路径: ...
随机推荐
- 容器化系列 - 通过Grafana监测InfluxDB数据 on Docker
本文演示在Docker中运行Grafana和InfluxDB,并通过Grafana展示InfluxDB曲线图. 1 准备工作 1.1 安装Docker 请参考这里 1.2 下载镜像 $ docker ...
- 商家APP店内点餐开启有桌台点餐模式
商家APP店内点餐开启有桌台点餐模式 步骤一:管理员后台-配置管理--店铺配置--简易付tab页--是否支持扫码下单-是 步骤二:管理员后台-配置管理--设备管理--选择对应的机器--配置--云POS ...
- web.xml设置过滤直接访问
<security-constraint> <web-resource-collection> <web-resource-name>JSPs</web-re ...
- c/c++ 多线程 boost的读写(reader-writer)锁
多线程 boost的读写(reader-writer)锁 背景:保护很少更新的数据结构时,c++标准库没有提供相应的功能. 例如:有个DNS条目缓存的map,基本上很少有更新,大部分都是读取,但是偶尔 ...
- MySql 学习之路-基础
Mysql 自学之路 本文包含基础部分与高级部分 一.基础 数据库操作 Show databases:显示所有的数据库 Show tables: 显示所有的数据库表 Use databasename: ...
- Spring Boot 正常启动后访问Controller提示404
问题描述 今天重新在搭建Spring Boot项目的时候遇到访问Controller报404错误,之前在搭建的时候没怎么注意这块.新创建项目成功后,作为项目启动类的Application在com.bl ...
- requests模块
import requests url='https://www.cnblogs.com/Eva-J/p/7277026.html' get = requests.get(url) print(get ...
- .NET CORE学习笔记系列(6)——KestrelServer
原文:http://www.cnblogs.com/artech/p/KestrelServer.html 跨平台是ASP.NET Core一个显著的特性,而KestrelServer是目前微软推出了 ...
- web 本地存储 (localStorage、sessionStorage)
web 本地存储 (localStorage.sessionStorage,cookie) localStorage(长期储存):即使关闭浏览器数据也不会删除,除非使用localStorage.cle ...
- 大数据处理框架之Strom:Flume+Kafka+Storm整合
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 storm-0.9 apache-flume-1.6.0 ...