完整代碼github地址:github.com/CTC-maxiao/…python
前面完成的程序太過簡單,不支持ansible的各類高級特性。因此咱們來一步步完善它的功能。首先須要完成的就是register和vars關鍵字。git
咱們首先來寫一個簡單的playbook來測試這些功能,而且能夠更清楚的幫助理解register和vars關鍵字。github
---
- name: test register and vars
host: localhost
vars:
source_machine: localhost
target_machine: localhost
tasks:
- task_name: test on source machine
become: yes
become_user: root
action_type: shell
action: cat test.txt
register: source_result
delegate_to: $$source_machine$$
- task_name: test on target machine
become: yes
become_user: root
action_type: shell
action: echo $$source_result$$
delegate_to: $$target_machine$$
複製代碼
這個playbook定義了兩個變量source_machine和target_machine,默認值都是localhost。因此若是沒有傳入這兩個變量的值的話,他們的值都會是localhost,兩個task都會在本機執行。shell
另外,咱們在第一個task中使用register關鍵字定義了一個變量source_result。並在第二個task中將這個變量的值輸出。bash
咱們須要將變量保存到一個字典中,這個字典咱們稱做爲變量字典。首先咱們須要讀取playbook中vars部分,將vars指定的變量以字典形式返回。若是playbook中沒有vars關鍵字,則返回空字典。在第三節咱們編寫了生成執行字典列表的函數get_final_task_list(),如今咱們來改寫這個函數來實現讀取vars的功能。函數
~~~~~~ #以上內容沒有修改
vars_dict = {}
for key,value in yaml_dict.items(): #將yaml文件中除task部分外的內容填入到模板字典中
if template_dict.has_key(key):
if key != "tasks":
self.template_dict[key] = value
elif key == "vars": #若是字典中有vars這個鍵,返回它的值
vars_dict = yaml_dict["vars"].copy() #vars的值是個字典,咱們使用copy()來返回字典的淺拷貝
~~~~~~ #如下內容沒有修改
return final_task_list,vars_dict #多返回一個返回值vars_dict
複製代碼
定義了變量以後,咱們還須要從外界輸入中向程序傳入變量的值。參考上一節,咱們爲傳入變量增長一個程序參數「-e」。程序會以以下格式接收變量的值:測試
python main.py -e "source_machine=192.168.1.104;target_machine=192.168.1.115" -u xxx -p xxx -y test.yaml
複製代碼
按照yaml文件中vars指定的變量名,以 「變量名=變量的值」的格式,不一樣變量之間用分號隔開。整個參數須要以引號包住。 關於如何增長程序參數能夠參考上一節內容,這裏就再也不贅述。咱們直接來看如何將傳入的參數轉換字典:ui
for param in vars_str.split(";"): #vars_str是咱們輸入的-e參數後的這一串字符,爲字符串類型
key = param.split("=")[0].strip() #將字符串以=分割,分別作爲字典的鍵和值
value = param.split("=")[1].strip()
vars_dict[key] = value #修改變量字典中變量的值
複製代碼
這樣咱們就把輸入的變量轉換爲了字典,而後修改變量字典中對應的變量。spa
修改playbook中的變量有兩種方式:code
通過以上考慮,咱們選擇第二種方法來修改變量。
def convert_task_vars(task_dict,vars_dict):
for task_key,task_value in task_dict.items(): #遍歷當前task的執行字典
for var_key,var_value in vars_dict.items(): #遍歷變量字典
convert_var = "$$"+var_key+"$$"
if type(task_value) == type(convert_var): #只有task中的value數據類型是字符串時才轉換變量
if convert_var in task_value:
task_value = task_value.replace(convert_var,var_value)
task_dict[task_key] = task_value
return task_dict
複製代碼
在每一個task執行前,咱們先執行這個函數來轉換task中的變量。
在每一個task執行以後判斷是否有register定義的變量。若是有就將變量和執行task的結果保存到變量字典中。
tmp_result = TaskExecutor.run_task(task) #tmp_result是執行task的返回值
if task["register"]: #若是task中使用register定義了變量
vars_dict[final_task["register"]] = tmp_result #加入到變量字典中
複製代碼