鍍金池/ 教程/ Python/ Python 批量更新 nginx 配置文件
通過 memcached 實現(xiàn)領(lǐng)號排隊功能及 python 隊列實例
利用 pypy 提高 python 腳本的執(zhí)行速度及測試性能
Python FAQ3-python 中 的原始(raw)字符串
Mongodb 千萬級數(shù)據(jù)在 python 下的綜合壓力測試及應(yīng)用探討
Parallel Python 實現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】
python simplejson 模塊淺談
服務(wù)端 socket 開發(fā)之多線程和 gevent 框架并發(fā)測試[python 語言]
python Howto 之 logging 模塊
python 之 MySQLdb 庫的使用
關(guān)于 python 調(diào)用 zabbix api 接口的自動化實例 [結(jié)合 saltstack]
python 之利用 PIL 庫實現(xiàn)頁面的圖片驗證碼及縮略圖
Python 通過 amqp 消息隊列協(xié)議中的 Qpid 實現(xiàn)數(shù)據(jù)通信
python 中用 string.maketrans 和 translate 巧妙替換字符串
python linecache 模塊讀取文件用法詳解
Python 批量更新 nginx 配置文件
python 計算文件的行數(shù)和讀取某一行內(nèi)容的實現(xiàn)方法
python+Django 實現(xiàn) Nagios 自動化添加監(jiān)控項目
多套方案來提高 python web 框架的并發(fā)處理能力
python 寫報警程序中的聲音實現(xiàn) winsound
python 調(diào)用 zabbix 的 api 接口添加主機、查詢組、主機、模板
對 Python-memcache 分布式散列和調(diào)用的實現(xiàn)
使用 python 構(gòu)建基于 hadoop 的 mapreduce 日志分析平臺
一個腳本講述 python 語言的基礎(chǔ)規(guī)范,適合初學(xué)者
Python 編寫的 socket 服務(wù)器和客戶端
如何將 Mac OS X10.9 下的 Python2.7 升級到最新的 Python3.3
python 監(jiān)控文件或目錄變化
報警監(jiān)控平臺擴展功能 url 回調(diào)的設(shè)計及應(yīng)用 [python 語言]
Python 處理 cassandra 升級后的回滾腳本
python 實現(xiàn) select 和 epoll 模型 socket 網(wǎng)絡(luò)編程
關(guān)于 B+tree (附 python 模擬代碼)
通過 python 和 websocket 構(gòu)建實時通信系統(tǒng)[擴展 saltstack 監(jiān)控]

Python 批量更新 nginx 配置文件

工作需要檢查線上所有服務(wù)器 ngxin 的 host 配置,是否都添加禁止訪問目錄中帶 /.svn/ 和以 tar.gz、tar、zip、等結(jié)尾 url,如果沒有則添加,由于線上 Nginx 服務(wù)器將近百臺,每臺的 nginx 配置至少 10 幾個,手工檢查太慢了,本人也不想浪費太多時間做這些無用功。故用 python 寫了一個檢測腳本。來完成這些無聊事情。

想用 python 完成這些事情,思路大概為:先備份每臺服務(wù)器原來的配置,然后遍歷每臺服務(wù)器內(nèi)所有 host 配置,正則匹配 host 配置看是否已經(jīng)添加相關(guān)配置,如有則跳過,遇到有但不全或沒有的則在對應(yīng)的位置上插入相應(yīng)的配置。除文本插入時我遇到一個問題外,其他比較簡單。因為 python 目前沒有對文本進行插入操作的模塊。整個插入過程需要自己一步一步實現(xiàn)。

當(dāng)時我考慮文本插入思路:把原配置文件載入內(nèi)存,正則找到要插入的位置,以此中心把原文件分成兩部分,開辟新內(nèi)存空間按順序先存放第一部內(nèi)容,然后存放出插入的內(nèi)容,然后存放第二部內(nèi)容。最后 flush 到硬盤。即通俗說法把原配置根據(jù)正則進行重定向。

我了解實現(xiàn)這種重定向有兩個方法,第一種: 打開原文件,根據(jù)規(guī)則重定向到新建的文件上。第二種:使用 fileinput 對原文件重定向。

下面是代碼,實現(xiàn)過程大概為:先判斷目錄 nginx 配置目錄,如果存在則備份,然后遍歷所有配置文件,匹配每個配置文件是否已添加相關(guān)內(nèi)容,如果沒有添加或者之前添加了部分內(nèi)容,找到配置文件第一個花括號“}”,下一行插入相應(yīng)的內(nèi)容。

#!/usr/bin/python
#coding:utf-8
#Author by Qfeian@20140215
"""
First backup file and then update all nginx configure
in the path "/usr/local/nginx/conf/vhosts".
Insert rule is to find the configure of the first "}"
after inserting content
"""
import fileinput
import os
import re
import sys
import string
import time
from subprocess import call
s_all = """
    location ~* ^(.*)\/\.svn\/ {
                deny all;
        }
        location ~* \.(tar|gz|zip|tgz|sh)$ {
                deny all;
        }
"""
s_svn = """
    location ~* ^(.*)\/\.svn\/ {
                deny all;
        }
"""
s_tar = """
        location ~* \.(tar|gz|zip|tgz|sh)$ {
                deny all;
        }
"""
def file_insert(fname, str):
        r = ur'}'
        f = open(fname)
        old = f.read()
        num = int(re.search(r, old).start())
        f_input = fileinput.input(fname, inplace=1)
        #for line in fileinput.input(fname, inplace=1):
        for line in f_input:
            if r in line:
                print line.rstrip()
                print "\n"+str+"\n"
                f.seek(num+2)
                print f.read()
                break
            else:
                print line.rstrip()
        f.close()
        f_input.close()
        #print "OK! The %s configure has been sucessfull added!" % fname
        print "Ok! 配置文件%s已經(jīng)添加成功!" % fname
def file_list(f_dir):
    #Check the content of configure,and add the correcsponding content
    rsvn = ur'\\\/\\.svn\\\/'
    rtar = ur'\(tar\|gz\|zip\|tgz\|sh\)'
    if os.path.exists(f_dir): #check dir
        for f_name in os.listdir(f_dir): #list the dir all configure file
           f_path = os.path.join(f_dir,f_name) #Get the filename full path
           f1 = open(f_path)
           f1_old = f1.read()
           f1.close()
           if re.findall(rsvn, f1_old) and re.findall(rtar, f1_old):
               #print "Notice!  %s have been added ,ignore this configure ...." % f_path
               print "Notice! %s 已添加過相關(guān)的配置,忽略此配置文件" % f_path
               continue
           elif re.findall(rsvn, f1_old):
               file_insert(f_path, s_tar)
           elif re.findall(rtar, f1_old):
               file_insert(f_path, s_svn)
           else:
               file_insert(f_path, s_all)
    else:
        print "Warnning! dir %s isn't exists!" % f_dir
def file_backup(f_dir):
    # If the file has been backed up with a minute before,will not back up
    bak_dir = "/data/nginx_config_bak/" + time.strftime('%Y%m%d_%H_%M')
    if not os.path.exists(bak_dir):
        os.makedirs(bak_dir)
        if os.path.exists(f_dir):
            cp = "cp -rp"
            cmd = "%s %s %s" % (cp, f_dir, bak_dir)
            call(cmd, shell=True) #backup the configure
if __name__ == "__main__":
    f_dir = "/usr/local/nginx/conf/vhosts"
    file_backup(f_dir)
    file_list(f_dir)
    print "-"*90,"\n 所有 Nginx 配置文件更新完成 !\n"

參考:

http://ryanstd.iteye.com/blog/480781

http://docs.python.org/2/library/fileinput.html