天天看點

ansible自定義子產品

參考官網:http://www.ansible.com.cn/docs/developing_modules.html#tutorial

閱讀 ansible 附帶的子產品(上面連結)是學習如何編寫子產品的好方法。但是請記住,ansible 源代碼樹中的某些子產品是内在的,是以請檢視service或yum,不要太靠近async_wrapper 之類的東西,否則您會變成石頭。沒有人直接執行 async_wrapper。

好的,讓我們開始舉例。我們将使用 Python。首先,将其儲存為名為timetest.py的檔案:

ansible自定義子產品
ansible自定義子產品

程式

ansible自定義子產品

[root@mcw1 ~]$ mkdir /usr/share/my_modules   #這個目錄并不存在,ansible配置中存在這個注釋掉的路徑

[root@mcw1 ~]$ vim uptime

執行結果:

ansible自定義子產品

[root@mcw1 ~]$ grep library /etc/ansible/ansible.cfg   #将配置中的這行内容注釋,取消掉,不需要重新開機任何服務

library = /usr/share/my_modules/

這裡顯示它使用的解釋器路徑了,這個解釋器是python2的解釋器,如果我寫的是python3的腳本,并且不支援python2執行,我可能需要修改ansible預設使用的python解釋器。有點問題,我腳本裡寫的是python2的解釋器,我寫成python3應該就是python3了吧

ansible自定義子產品

按照上面想法試了下,果然是的,我另一個主機是沒有安裝python3的,是以報錯了。使用python3,貌似不會顯示python的路徑,跟之前python2有點差別

ansible自定義子產品

編寫腳本:

ansible自定義子產品

程式如下:

上面程式中,python2和python3去掉\n換行符存在差別。python2:rstrip("\n"),python3:rstrip("\\n")

無論是否dumps,列印結果都是一行。當将字典dumps後,結果好看很多

ansible自定義子產品

 當不使用dumps時,都是報錯,但是有标準輸出的還是會一行列印出來

ansible自定義子產品

 當我程式裡将字典換成一行時,ansible輸出内容還是有層次的顯示出來。并且它把我們輸出的字典所有鍵值對,相當于批量追加進ansible自己的輸出字典中。同時它還會有自己的相關鍵值對,

ansible自定義子產品

總結:我們可以寫python(shell應該也可以)腳本,将需要的資訊建構字典,列印出來。然後将腳本放到自定義子產品目錄下,無需添加執行權限,就可以使用ansible調用自定義子產品,将輸出結果顯示在ansible的列印結果字典中

 思考:上面總結列印的結果我怎麼用?python中如何使用這個結果,ansible劇本中是否能使用這個子產品,如何使用,這麼用到它的列印結果?

使用shell的方法還存在問題,有時間再看有辦法解決這個問題

ansible自定義子產品

設定變量,其它地方使用變量

我們通過set_fact子產品定義了一個名為testvar的變量,變量值為testtest,然後使用debug子產品輸出了這個變量:

ansible自定義子產品

如下:

ansible自定義子產品
ansible自定義子產品

劇本2

在劇本中定義變量testvar1,在劇本中可以引用這個變量。執行shell指令,将指令傳回值注冊為一個變量。set_fact子產品設定兩個變量,變量1讓它等于前面設定的變量testvar1,變量2給它指派shell指令的傳回結果變量的标準輸出。後面對這兩個變量列印檢視

劇本中想要檢視資訊,需要使用debug 子產品(debug msg 列印)

set_fact:可以自定義變量,可以進行變量值的傳遞。可以用這個子產品重新定義一個變量去接收其它變量的值,包括接收其它注冊的變量值 

ansible自定義子產品

上例中,我們先定義了一個變量testvar1,又使用register将shell子產品的傳回值注冊到了變量shellreturn中,

之後,使用set_fact子產品将testvar1變量的值賦予了變量testsf1,将shellreturn變量中的stdout資訊指派給了testsf2變量,(可以将注釋去掉檢視變量shellreturn的值)

最後,使用debug子產品輸出了testsf1與testsf2的值:

如上述示例所示,set_fact子產品可以讓我們在tasks中建立變量,也可以将一個變量的值指派給另一個變量。

其實,通過set_fact子產品建立的變量還有一個特殊性,通過set_fact建立的變量就像主機上的facts資訊一樣,可以在之後的play中被引用。

預設情況下,每個play執行之前都會執行一個名為”[Gathering Facts]”的預設任務,這個任務會收集對應主機的相關資訊,我們可以稱這些資訊為facts資訊,我們已經總結過怎樣通過變量引用這些facts資訊,此處不再贅述,而通過set_fact子產品建立的變量可以在之後play中被引用,就好像主機的facts資訊可以在play中引用一樣,這樣說可能還是不是特别容易了解,不如來看一個小例子,如下

ansible自定義子產品
ansible自定義子產品

劇本

ansible自定義子產品

 變量1是vars關鍵字設定變量,在目前play生效,不能跨越play使用變量,但是變量2卻可以跨越play使用變量,變量2是set_facts子產品設定變量

ansible自定義子產品

可以發現,這兩個變量在第一個play中都可以正常的輸出。但是在第二個play中,testvar2可以被正常輸出了,testvar1卻不能被正常輸出,會出現未定義testvar1的錯誤,因為在第一個play中針對testB主機進行操作時,testvar1是通過vars關鍵字建立的,而testvar2是通過set_fact建立的,是以testvar2就好像testB的facts資訊一樣,可以在第二個play中引用到,而建立testvar1變量的方式則不能達到這種效果,雖然testvar2就像facts資訊一樣能被之後的play引用,但是在facts資訊中并不能找到testvar2,隻是”效果上”與facts資訊相同罷了。

ansible自定義子產品
ansible自定義子產品
ansible自定義子產品

3是vars定義變量,4是注冊變量,4是可以跨play的,3卻不行 。是需要4還是3看情況

ansible自定義子產品

在第二個play中擷取”testvar3″時會報錯,而在第二個play中擷取注冊變量”testvar4″時則正常,但是,注冊變量中的資訊是子產品的傳回值,這并不是我們自定義的資訊,是以,如果想要在tasks中給變量自定義資訊,并且在之後的play操作同一個主機時能夠使用到之前在tasks中定義的變量時,則可以使用set_facts定義對應的變量。

上述示例中,即使是跨play擷取變量,也都是針對同一台主機。

找到過濾插件所在的目錄,目前沒有任何過濾插件,新增一個插件deal_list_num.py

[root@mcw1 ~]$ ls /usr/share/ansible/plugins/filter

deal_list_num.py

 插件的好處在于編寫YML檔案時可以減少我們的工作量,而且結果易于展示,隻要學習一些比較重要的比如Filter、Callbacks等即可。

    在普通情況下,我們主要是以{{somevars|filter}對somevars使用filter方法過濾,Ansible已經為我們提供了很多的過濾方法,比如找到清單中最大、最小數的max、min,把資料轉換成JSON格式的fromjson等,但這還遠遠不夠,我們還需要自定義一些過濾的方法來滿足一些特殊的需求,比如查找清單中大于某個常數的所有數字等。以這個例子,展示如何編寫。

    首先,到ansible.cfg中去掉#,打開filter_plugins的存放目錄,filter_plugins=/usr/share/ansible/plugins/filter。

    編寫deal_list_num.py檔案,他主要提供過濾清單中的正數、負數和查詢清單大于某一個給定數值這3個方法。/usr/share/ansible/filter/deal_list_num.py。

ansible自定義子產品
ansible自定義子產品
ansible自定義子產品

第一個是取清單中的正數,第二個是取清單中的負數。第三個是取清單中不小于4的數

ansible自定義子產品
ansible自定義子產品

變量引用和檢視擷取shell指令結果作為注冊變量,該如何取到指令結果

ansible自定義子產品
ansible自定義子產品

過濾方法這裡做個修改

ansible自定義子產品
ansible自定義子產品

 總結:

1、過濾插件定義類,類中定義方法,方法傳回内容

2、将過濾插件放到ansible過濾插件目錄下

3、劇本中{{變量}}的方式調用變量。然後變量後面|加過濾方法。這樣就可以将變量傳遞進插件對應方法中,除了self之外的第一個位置參數就是這個劇本中的變量。

4、在過濾插件方法中對這個變量做過濾,然後傳回結果(這裡是定義空清單,然後将劇本變量清單周遊一次,篩選出指定條件的元素追加到新的清單中,方法傳回新的清單這樣劇本中就是使用過濾後的資料)

 參考位址:

劇本編寫和定義子產品: https://blog.csdn.net/weixin_46108954/article/details/104990063

設定和注冊變量:https://blog.csdn.net/weixin_45029822/article/details/105280206

自定義插件:過濾插件:https://blog.csdn.net/JackLiu16/article/details/82121044