python自動化運維5--系統批量運維管理器Fabric使用

在講Fabric之前我們先說下另外兩個跟Fabric有相似功能的模塊:
1.pexpect
pexpect可以理解成Linux下的expect的Python封裝,通過pexpect我們可以實現對ssh、ftp、passwd、telnet等命令行進行自動交互,而無需人工干涉來達到自動化的目的。比如我們可以模擬一個FTP登錄時的所有交互,包括輸入主機地址、用戶名、密碼、上傳文件等,待出現異常我們還可以進行嘗試自動處理。
2.paramiko:
paramiko是基於Python實現的SSH2遠程安全連接,支持認證及密鑰方式。可以實現遠程命令執行、文件傳輸、中間SSH代理等功能,相對於Pexpect,封裝的層次更高,更貼近SSH協議的功能。
3.Fabric:
Fabric是基於Python(2.5及以上版本)實現的SSH命令行工具,簡化了SSH的應用程序部署及系統管理任務,它提供了系統基礎的操作組件,可以實現本地或遠程shell命令,包括命令執行、文件上傳、下載及完整執行日誌輸出等功能。Fabric在paramiko的基礎上做了更高一層的封裝,操作起來會更加簡單。

前兩個模塊基本可以實現Fabric的功能,但是使用起來會比較複雜,所以基本上我們更多使用的是Fabric模塊。

關於fabric的中文文檔可以看下這個鏈接

常用API

Fabric提供了一組簡單但功能強大的fabric.api命令集,簡單地調用這些API就能完成大部分應用場景需求。Fabric支持常用的方法及說明如下:
·local,執行本地命令,如:local(‘uname-s’);
·lcd,切換本地目錄,如:lcd(’/home’);
·cd,切換遠程目錄,如:cd(’/data/logs’);
·run,執行遠程命令,如:run(‘free-m’);
·sudo,sudo方式執行遠程命令,如:sudo(’/etc/init.d/httpdstart’);
·put,上傳本地文件到遠程主機,如:put(’/home/user.info’,’/data/user.info’);
·get,從遠程主機下載文件到本地,如:get(’/data/user.info’,’/home/root.info’);
·prompt,獲得用戶輸入信息,如:prompt(‘please input user password:’);
·confirm,獲得提示信息確認,如:confirm(“Testsfailed.Continue[Y/N]?”);
·reboot,重啓遠程主機,如:reboot();
·@task,函數修飾符,標識的函數爲fab可調用的,非標記對fab不可見,純業務邏輯;
·@runs_once,函數修飾符,標識的函數只會執行一次,不受多臺主機影響。

案例1查看本地與遠程主機信息

注意:我使用的數python3,所以下載此模塊使用的是:

pip install fabric3

本示例調用local()方法執行本地(主控端)命令,調用run()方法執行遠程命令,

from fabric.api import *

#此文件命名爲test.py

env.user='root'
env.hosts=['192.168.1.103]
env.password='123df'

@runs_once #查看本地系統信息,當有多臺主機時只運行一次
def local_task(): #本地任務函數
    local("ipconfig")

def remote_task():
    with cd("/home"): #“with”的作用是讓後面的表達式的語句繼承當前狀態,現
        run("ls -l") # “cd /home && ls -l”的效果

然後在命令行輸入下面命令,:

#執行local_task函數
fab -f test.py local_task

#執行remote_task函數
fab -f test.py remote_task

fab是fabric內置的命令,它作爲Fabric程序的命令行入口,提供了豐富的參數調用。test.py則是我們上面程序的文件名,然後後面就是我們定義的要執行的函數名。因爲我用的是windows系統,所以我先在本機執行local_task函數,並執行ipconfig命令來查看當前的網絡狀態。接着我調用remote_task函數,並使用命令查看遠程主機的信息。你們可能會疑惑,它怎麼跟遠程主機建立連接呢,那些fabric模塊底層都幫我們封裝好了,我們只要在程序一開始指定好環境變量env,設置好我們要登錄的遠程主機的用戶名,IP,密碼就可以了,默認使用的是ssh連接,也就是使用22端口,我們也可以指定指定爲其他端口:env.port=23。

案例2動態獲取遠程目錄列表

from fabric.api import *

#此文件命名爲test.py

env.user='root'
env.hosts=['192.168.1.103]
env.password='123df'

def input_raw():                                                        
    return prompt("please input directory name:",default="/home")       
                                                                        
def worktask(dirname):                                                  
    run("ls -l "+dirname)                                               
                                                                        
@task #限定只有go函數對fab命令可見                                                 
def go():                                                               
    getdirname = input_raw()                                            
    worktask(getdirname)                                                	

然後在命令行輸入下面命令:

#執行go函數
fab -f test.py go

該示例實現了一個動態輸入遠程目錄名稱,再獲取目錄列表的功能,由於我們只要求輸入一次,再顯示所有主機上該目錄的列表信息,調用了一個子函數input_raw()同時配置@runs_once修飾符來達到此目的。

案例3文件打包、上傳與校驗

我們時常做一些文件包分發的工作,實施步驟一般是先壓縮打包,再批量上傳至目標服務器,最後做一致性校驗。本案例通過put()方法實現文件的上傳,通過對比本地與遠程主機文件的md5,最終實現文件一致性校驗。

from fabric.api import *
from fabric.context_managers import *         
from fabric.contrib.console import confirm   
 
#此文件命名爲test.py

env.user='root'
env.hosts=['192.168.1.103]
env.password='123df'

@task                                                                           
@runs_once                                                                      
def tar_task(): #本地打包任務函數,只限執行一次                                                
    with lcd("/data/logs"):                                                     
        local("tar -czf access.tar.gz access.log")                              
                                                                                
@task                                                                           
def put_task(): #上傳文件任務函數                                                       
    run("mkdir -p /data/logs")                                                  
    with cd("/data/logs"):                                                      
        with settings(warn_only=True): #put(上傳)出現異常時繼續執行,非終止                    
            result = put("/data/logs/access.tar.gz","/data/logs/access.tar.gz") 
            if result.failed and not confirm("put file failed,Continue[Y/N]?"): 
                abort("Aborting file put task!") #出現異常時,確認用戶是否繼續,(Y繼續)          
                                                                                
@task                                                                           
def check_task(): #校驗文件任務函數                                                     
    with settings(warn_only=True):                                              
        #本地local命令需要配置capture=True才能捕獲返回值                                       
        lmd5=local("md5sum /data/logs/access.tar.gz",                           
        capture=True).split(' ')[0]                                             
        rmd5=run("md5sum /data/logs/access.tar.gz").split(' ')[0]               
        if lmd5==rmd5: #對比本地及遠程文件md5信息                                          
            print("OK")                                                         
        else:                                                                   
            print("ERROR")                                                      
                                                                                
@task                                                                           
def go():                                                                       
    tar_task()                                                                  
    put_task()                                                                  
    check_task()                                                                

然後在命令行輸入下面命令,就可以實現文件打包、上傳、校驗全程自動化:

#執行go函數
fab -f test.py go
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章