python學習之路之案例1(修改haproxy的配置文件,並實現下線、上線的功能)

整個案例運用的知識點:python

  1.python基本數據結構的使用:列表、字典等json

  2.python兩個模塊的使用:os和json後端

      1.os.rename('文件1','文件2')bash

      2.json完成自動識別字典、列表,並識別後進行自動轉換數據結構

  3.python函數的定義和調用app

  4.標誌位的靈活運用:frontend

            1.flag用於找backendide

            2.haswrite用於找record和判斷是否已經將記錄寫入到文件函數

  5.python基本語法的使用:fetch

            1.for循環

            2.if...else....判斷

  6.python文件的操做的基本使用:

            1.with open('文件1','模式') as obj1,open('文件2','模式') as obj2


整個代碼的中心思想:

    1.設置2個文件:源文件ha和終文件ha.new(整個過程是:邊讀邊寫)

            1.源文件ha用於提供讀

            2.終文件ha.new用於提供寫

    2.上線、下線的巧妙應用:

            1.下線:將源文件ha  rename 成備用文件ha.bak

            2.上線:將終文件ha.new rename 成新的配置文件ha



代碼實現的功能:

    1.查找ha文件中指定backend下的後端主機列表信息

    2.增長ha文件中指定backend以及backend後端主機列表信息

    3.刪除ha文件中指定backend以及backend後端主機列表信息

    4.增長和刪除操做以後,讓新的配置文件上線,原來的配置文件下線


配置文件(即ha)

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 jachy.org
        bind 0.0.0.0:80
        option httplog
        option httpclose
        option  forwardfor
        log global
        acl www hdr_reg(host) -i www.jachy.org
        use_backend www.jachy.org if www

backend www.jachy.org
        server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000


代碼:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#導入2個模塊json和os
import  json,os

#定義fetch函數,並同時傳入咱們指定backend參數,此參數表明backend名
def fetch(backend):
    flag = False #定義flag,目的是爲了後面是否取可用的backend
    fetch_list=[]  #定義空列表,目的是爲了後面將取出的backend信息存儲在此列表裏面

    #以讀的形式打開'ha'文件,一行一行讀,而後將咱們指定backend讀取到列表裏面
    #最後返回裝有咱們指定backend信息的列表
    with open('ha') as obj:
        for line in obj:
            if line.strip() == "backend %s" %(backend):
                flag = True
                continue
            if line.strip().startswith('backend'):
                flag=False
            if flag and line.strip():
                fetch_list.append(line.strip())

    return fetch_list

#定義add1函數,並同時傳入參數dict_info,此字典參數裏面包含咱們要傳入的server相關信息
def add1(dict_info):

    backend_title = dict_info.get("backend") #要插入的backend的名稱
    context_title = "backend %s" %(backend_title)  #要插入backend整個字段
    record_title = dict_info["record"]
    #要插入的記錄信息
    context_record = "server %s %s weight %s maxconn %s" %(record_title["server"],record_title["server"],record_title["weight"],record_title["maxconn"])

    #將backend獲取,並存儲在fetch_list列表裏面
    fetch_list=fetch(backend_title)

    #若是要插入的backend存在
        #1.首先設定2個標誌:flag和has_write
            #flag:用於找到要添加的backend下的內容
            #has_write:用於判斷fetch_list中的內容是否從新寫入到了文件
        #2.遍歷源文件ha:
            #1首先逐行讀取,並同時進行判斷,
                # 1.判斷backend是否已經找到,先把backend寫入文件,而後找到後將flag設置爲True,最後跳出本次循環
                # 2.判斷找到的backend裏面的record是否爲空,若爲空將flag設置爲False
                # 3.對flag進行判斷
                    #1.將flag爲True的record從fetch_list寫入到文件中,在這裏面同時要進行是否已經寫入的判斷,即定義has_write的做用
                    #2.若flag爲False,就直接寫入新文件,即將非列表裏的內容直接寫入

    if fetch_list:
        flag=False
        has_write = False
        with open('ha') as read_obj,open('ha.new','w') as write_obj:
            for line in read_obj:
                if line.strip() == context_title:
                    write_obj.write("\n"+line)
                    flag=True
                    continue
                if flag and line.startswith('backend'):
                    flag = False
                if flag:
                    for new_line in fetch_list:
                        if not has_write:
                            temp = "%s%s" %(" "*8,new_line)
                            write_obj.write(temp)
                            has_write=True
                else:
                    write_obj.write(line)


    else:
    #若是要插入的backend不存在
        #分2部分寫入:
            # 1部分.從ha文件裏面直接讀取,並同時將讀取的內容寫入新的文件ha.new
            # 2部分.將新的backend和context信息,直接寫到新的文件ha.new的文件尾部
        with open('ha') as read_obj,open('ha.new','w') as write_obj:
            for line in read_obj:
                write_obj.write(line)
            write_obj.write("\n"+context_title+"\n")
            temp=" "*8+context_record+"\n"
            write_obj.write(temp)

    #將原文件ha更名備用文件爲ha.bak,即將ha下線
    #將新文件ha.new更名爲線上文件ha,即將ha.new上線
    os.rename('ha','ha.bak')
    os.rename('ha.new','ha')


#刪除函數
def delete(dict_info):
    #1.首先獲取用戶的記錄並以列表的形式存儲,以便於咱們調用
    del_backend = dict_info["backend"]
    del_record = dict_info["record"]

    context_title = "backend %s" %(del_backend)
    context_record = "server %s %s weight %s maxconn %s" %(del_record["server"],del_record["server"],del_record["weight"],del_record["maxconn"])

    #調用上面定義的fetch()函數,獲得包含backend內容的列表
    fetch_list = fetch(del_backend)
    #判斷1:若列表爲空:直接返回
    if not fetch_list:
        return
    #判斷2:不然不爲空
    else:
        #判斷1:若用戶輸入的server信息不在fetch_list裏面,直接返回
        if context_record not in fetch_list:
            print "your server message is not exists"
            return
        #判斷2:若輸入的server在fetch_list裏面,就將此server信息從列表中移除
        else:
            fetch_list.remove(context_record)

        #逐行從ha文件中讀取,並同時進行判斷
        #核心思想:
            #首先邊讀取、邊判斷、邊寫入,
            # 判斷其實就是咱們本身輸入的backend,找到後將列表fetch_list信息寫入到新的文件裏面。
            # 其他的非列表的內容直接從源文件ha寫到新文件ha.new便可
        with open('ha','r') as read_obj,open('ha.new','w') as write_obj:
            flag = False
            has_write = False
            for line in read_obj:
                if line.strip() == context_title:
                    write_obj.write(line)
                    flag = True
                    continue
                if flag and line.startswith('backend'):
                    flag = False
                if flag:
                    if not has_write:
                        print fetch_list
                        for new_line in fetch_list:
                            temp = "%s%s\n" %(" "*8,new_line)
                            write_obj.write(temp)
                        has_write = True
                else:
                    write_obj.write(line)

    #將原文件ha更名備用文件爲ha.bak,即將ha下線
    #將新文件ha.new更名爲線上文件ha,即將ha.new上線
    os.rename('ha','ha.bak')
    os.rename('ha.new','ha')


"""
s='{"backend":"ttt.jachy.org","record":{"server":"100.1.7.9","weight":"20","maxconn":"3000"}}'
data_info=json.loads(s)
add1(data_info)
#delete(data_info)
"""

#主函數
if __name__ == "__main__":
    #獲取用戶的操做選擇
    print u"1.獲取記錄\n2.添加記錄\n3.刪除記錄\n"
    select_num=raw_input("plz input number:")

    #根據用戶的選擇,進行調用函數
    if select_num == "1":
        backend = raw_input("plz input backend:")
        fetch_list = fetch(backend)
        for i in fetch_list:
            print i
    else:
        print "plz input like this example:"
        print '{"backend":"ttt.jachy.org","record":{"server":"100.1.7.9","weight":"20","maxconn":"3000"}}'
        data_str = raw_input("plz input record>>>")
        data_dict = json.loads(data_str)
        if select_num == "2":
            add1(data_dict)
        elif select_num == "3":
            delete(data_dict)
        else:
            print "input error"
相關文章
相關標籤/搜索