1. 程式人生 > >haproxy.cfg 配置檔案 python指令碼管理

haproxy.cfg 配置檔案 python指令碼管理


HAproxy.cfg 事例檔案

global
    log 127.0.0.1 local1 notice
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    pidfile /usr/local/haproxy/logs/haproxy.pid
    stats socket /var/tmp/haproxy.sock level admin
defaults
    mode tcp
    retries    3
    option abortonclose
    log    global
    option    dontlognull
    stats auth qqadmin:qqadmin
backend ptone-datadeck
    mode http
    option forwardfor
    option httpclose
    server s1 10.1.4.14:6060 check
backend ptone-auth
    mode http
    option forwardfor
    option httpclose
    server 01 10.1.4.16:8181 check
frontend ptone
    bind 10.1.3.222:80
    mode http
    log global
    acl datadeck_qq_com hdr(host) -i datadeck.qq.com use_backend ptone-datadeck if datadeck_qq_com
    acl ptoneauth_qq_com hdr(host) -i ptoneauth.qq.com use_backend ptone-auth if ptoneauth_qq_com
frontend http-in
    bind 220.248.107.234:80
    mode http
    log global
    acl u_8 hdr_end(host) -i u8.qq.com use_backend u8.qq.com if u_8
    acl paycbm hdr_end(host) -i paycbm.qq.com use_backend paycbm.qq.com if paycbm
listen guest_stats
    stats   enable
    bind    *:9081
    mode    http
    stats   refresh 30s
    stats   uri /guest-stats
listen web_poll 10.1.3.222:9200
    mode http
    option httplog
    option dontlognull
    option logasap
    option forwardfor
    option httpclose
    server 10.1.3.23  10.1.3.23:9201 cookie app02 check inter 5s rise 3 fall 3 weight 1
    server 10.1.3.25  10.1.3.25:9200 cookie app03 check inter 5s rise 3 fall 3 weight 1
下面是寫的配置管理指令碼 因為沒有寫成類 所以每個方法都重新開啟檔案
from collections import OrderedDict
'''
haproxy.conf配置檔案分為以下幾個部分
第一部分:global  defaults
第二部分:backend
第三部分:frontend
第四部分:listen
'''

# 獲取前半部分內容 (第一部分)
# def get_one():
#     record_list=[]
#     with open('haproxy.conf', 'r', encoding='utf-8') as obj:
#         flag = False
#         x = False
#         for line in obj:
#             line = line.replace("\n","")
#             if 'backend' in line:
#                 break
#             else:
#                 record_list.append(line)
#     return record_list
def get_top_info():
    dic=OrderedDict()
    with open('haproxy.conf', 'r', encoding='utf-8') as obj:
        flag = False
        ll=[]
        name=''
        for line in obj:
            line = line.replace("\n", "")
            if 'backend' in line:
                break
            else:
                if line.startswith("  "):
                    ll.append(line)
                else:
                    if name=='':
                        flag=True
                        name=line
                        ll.append(name)
                    else:
                        dic[name]=ll
                        name=line
                        ll.append(name)
    return dic
# 獲取backend所有的名稱
def get_backend_name():
    namelist=[]
    with open('haproxy.conf','r',encoding='utf-8') as obj:
        for line in obj:
            line = line.strip()
            if 'backend' in line and 'use_backend' not in line:
                namelist.append(line)
    return namelist
# 獲取所有backend主機組(第二部分)
def get_backend_info(backtitle):
    record_list = []
    with open('haproxy.conf','r',encoding='utf-8') as obj:
        flag = False
        x=False
        for line in obj:
            line = line.replace("\n","")
            if line == backtitle:
                record_list.append(line)
                flag = True
                x = False
                continue
            if 'server' in line:
                x = True
            if flag and line.startswith('backend'):
                flag = False
                break
            if flag and line:
                if x:
                    if 'server' in line:
                        record_list.append(line)
                    else:
                        break
                else:
                    record_list.append(line)
    return record_list
# 查詢出所有的backend值 生成有序字典
def backend_info():
    dic=OrderedDict()
    for backend_name in get_backend_name():
        dic[backend_name]=get_backend_info(backend_name)
    return dic
# 更新server  提供server 和伺服器地址 生成新的dic
# 如  name='xxxxx.qq.com' info='server 10.10.10.10 10.10.10.10:8088'
# 前面會自動加四個空格
def update_server(name,info):
    name='backend %s' %name
    info="    %s" %info
    dic=backend_info()
    ll=[]
    if name in dic:
        ll=list(dic[name])
        if info not in ll:
            ll.append(info)
    else:
        ll=[name,"    mode http","    option forwardfor",info]
    print (ll)
    dic[name]=ll
    return dic
'''
fw = open("test.conf", 'w', encoding='utf-8')
dic=update_server('xxxxx.uzai.com','server 10.10.10.10 10.10.10.10:8088')

for x,v in dic.items():
    for vv in v:
        fw.write(vv+"\n")
fw.close()
'''
'''
# 獲取frontend的名稱
'''
def get_frontend_name():
    namelist=[]
    with open('haproxy.conf','r',encoding='utf-8') as obj:
        for line in obj:
            line = line.strip()
            if 'frontend' in line:
                namelist.append(line)
    return namelist


# 根據frontend的名字來獲取資訊
def get_frontend_name_info(name):
    record_list = []
    with open('haproxy.conf', 'r', encoding='utf-8') as obj:
        flag = False
        x = False
        for line in obj:
            line = line.replace("\n", "")
            if line == name:
                record_list.append(line)
                flag = True
            if flag and line.startswith('    '):
                x = True

            if flag and x:
                if line.startswith('  ') or line.startswith("\t"):
                    record_list.append(line)
                else:
                    break
    return record_list

'''
獲取frontend 全部資訊
'''
def frontend_info():
    dic=OrderedDict()
    for frontend_name in get_frontend_name():
        dic[frontend_name]=get_frontend_name_info(frontend_name)
    return dic

'''
更改或增加域名的的ACL資訊
當fronted_name 和acl_name 和acl_domain  都一樣的時候 只更改acl_backend的時候
只更改  如果資訊對不上。那就增加
fronted_name="ptone"
acl_name='datadeck_uzai_com'
acl_domain='datadeck.uzai.com'
acl_backend='xxxxxxxxxxxxxxx'
'''
def update_fronted_acl(fronted_name,acl_name,acl_domain,acl_backend):
    fronted_name = "frontend " + fronted_name
    acl_info="    acl %s hdr(host) -i %s use_backend %s if %s" %(acl_name,acl_domain,acl_backend,acl_name)
    flag = False
    dic_frontend=frontend_info()

    for k, v in dic_frontend.items():
        if k == fronted_name:
            acl_list_nb = -1
            acl_list = list(v)
            if acl_info in acl_list:
                break
            else:
                for l in acl_list:
                    acl_list_nb += 1
                    acl_info_list = str(l).split(' ')
                    if len(acl_info_list) > 8:
                        if acl_info_list[5] == acl_name or acl_info_list[8] == acl_domain:
                            flag = True
                            acl_list[acl_list_nb] = acl_info
                            dic_frontend[fronted_name] = acl_list
                            break
            if flag == False:
                acl_list.append(acl_info)
                dic_frontend[fronted_name] = acl_list
    return dic_frontend

# 獲取所有listen名稱
def get_listen_name():
    namelist=[]
    with open('haproxy.conf','r',encoding='utf-8') as obj:
        for line in obj:
            line = line.strip()
            if 'listen' in line:
                namelist.append(line)
    return namelist

# 根據listen的名字來查獲取資訊
def get_listen_info(name):
    list_listen=[]
    with open('haproxy.conf','r',encoding='utf-8') as obj:
        flag = False
        x = False
        for line in obj:
            line = line.replace("\n", "")
            if line==name:
                list_listen.append(line)
                flag=True
            if flag and line.startswith('    '):
                x = True
            if flag and x:
                if line.startswith('  ') or line.startswith("\t"):
                    list_listen.append(line)
                else:
                    break
    return list_listen


#獲取全部listen的名字
def listen_info():
    dic=OrderedDict()
    for listen_name in get_listen_name():
        dic[listen_name]=get_frontend_name_info(listen_name)
    return dic

def write_file(dic,fw):
    for k,v in dic.items():
        for vv in v:
            fw.write(vv+"\n")

def new_file(top,bakend,frontend,listen):
    fw = open("test.conf", 'w', encoding='utf-8')
    write_file(top,fw)
    write_file(bakend,fw)
    write_file(frontend,fw)
    write_file(listen,fw)
    fw.close()

======使用方法 1:============================================================================== 下面寫怎麼使用
#寫入全新的檔案  (方法裡面定義了新的檔名稱)
new_file(get_top_info(),backend_info(),frontend_info(),listen_info())

結果如下 test.conf
global
    log 127.0.0.1 local1 notice
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    pidfile /usr/local/haproxy/logs/haproxy.pid
    stats socket /var/tmp/haproxy.sock level admin
defaults
    mode tcp
    retries    3
    option abortonclose
    log    global
    option    dontlognull
    stats auth qqadmin:qqadmin
backend ptone-datadeck
    mode http
    option forwardfor
    option httpclose
    server s1 10.1.4.14:6060 check
backend ptone-auth
    mode http
    option forwardfor
    option httpclose
    server 01 10.1.4.16:8181 check
frontend ptone
    bind 10.1.3.222:80
    mode http
    log global
    acl datadeck_qq_com hdr(host) -i datadeck.qq.com use_backend ptone-datadeck if datadeck_qq_com
    acl ptoneauth_qq_com hdr(host) -i ptoneauth.qq.com use_backend ptone-auth if ptoneauth_qq_com
frontend http-in
    bind 220.248.107.234:80
    mode http
    log global
    acl u_8 hdr_end(host) -i u8.qq.com use_backend u8.qq.com if u_8
    acl paycbm hdr_end(host) -i paycbm.qq.com use_backend paycbm.qq.com if paycbm
listen guest_stats
    stats   enable
    bind    *:9081
    mode    http
    stats   refresh 30s
    stats   uri /guest-stats
listen web_poll 10.1.3.222:9200
    mode http
    option httplog
    option dontlognull
    option logasap
    option forwardfor
    option httpclose
    server 10.1.3.23  10.1.3.23:9201 cookie app02 check inter 5s rise 3 fall 3 weight 1
    server 10.1.3.25  10.1.3.25:9200 cookie app03 check inter 5s rise 3 fall 3 weight 1

======使用方法 2:============================================================================= 修改acl 增加
fronted_name="ptone"
acl_name='web_qq'
acl_domain='test.qq.com'
acl_backend='ptone-datadeck'
new_backend_info=update_fronted_acl(fronted_name,acl_name,acl_domain,acl_backend)
new_file(get_top_info(),backend_info(),new_backend_info,listen_info())
結果如下
frontend ptone
    bind 10.1.3.222:80
    mode http
    log global
    acl datadeck_qq_com hdr(host) -i datadeck.qq.com use_backend ptone-datadeck if datadeck_qq_com
    acl ptoneauth_qq_com hdr(host) -i ptoneauth.qq.com use_backend ptone-auth if ptoneauth_qq_com
    acl web_qq hdr(host) -i test.qq.com use_backend ptone-datadeck if web_qq
frontend http-in
    bind 220.248.107.234:80
    mode http
    log global
    acl u_8 hdr_end(host) -i u8.qq.com use_backend u8.qq.com if u_8
    acl paycbm hdr_end(host) -i paycbm.qq.com use_backend paycbm.qq.com if paycbm
修改
fronted_name="http-in"
acl_name='paycbm '
acl_domain='u8.qq.com'
acl_backend='ptone-auth'
new_backend_info=update_fronted_acl(fronted_name,acl_name,acl_domain,acl_backend)
new_file(get_top_info(),backend_info(),new_backend_info,listen_info())

結果如下
frontend ptone
    bind 10.1.3.222:80
    mode http
    log global
    acl datadeck_qq_com hdr(host) -i datadeck.qq.com use_backend ptone-datadeck if datadeck_qq_com
    acl ptoneauth_qq_com hdr(host) -i ptoneauth.qq.com use_backend ptone-auth if ptoneauth_qq_com
frontend http-in
    bind 220.248.107.234:80
    mode http
    log global
    acl u_8  hdr(host) -i u8.qq.com use_backend ptone-auth if u_8    (u8.qq.com  改成了 ptone-auth)
    acl paycbm hdr_end(host) -i paycbm.qq.com use_backend paycbm.qq.com if paycbm

======使用方法 3:============================================================================= 修改伺服器
dic=update_server('ptone-datadeck','server 10.10.10.10 10.10.10.10:8088')
new_file(get_top_info(),dic,frontend_info(),listen_info())
結果如下
backend ptone-datadeck
    mode http
    option forwardfor
    option httpclose
    server s1 10.1.4.14:6060 check
    server 10.10.10.10 10.10.10.10:8088
backend ptone-auth
    mode http
    option forwardfor
    option httpclose
    server 01 10.1.4.16:8181 check