然而 Ansible 在2.0版本後重構了大部分的代碼邏輯, 啟用了2.0版本之前的 Runner 和 Playbook 類, 使得廣大同學之前的代碼運行錯誤. 擇日不如撞日, 今天中午對照 官方的文檔 , 結合源代碼, 對2.0版本之後的 Python API 做了下探究
Adhoc
adhoc 其實就是執行 Ansible 模塊, 通過 adhoc 我們可以方便快捷的完成壹些臨時的運維操作.
2.0 之前的調用
import ansible.runner
import json
runner = ansible.runner.Runner(
module_name='ping', # 模塊名
module_args='', # 模塊參數
pattern='all', # 目標機器的pattern
forks=10
)
datastructure = runner.run()
data = json.dumps(datastructure,indent=4)
當然這裏會去加載默認的 inventory
如果不想使用 inventory 文件或者想使用動態的 inventory, 則可以使用 host_list 參數代替
import ansible.runner
import json
runner = ansible.runner.Runner(
host_list=["10.10.0.1"], # 這裏如果明確指定主機需要傳遞壹個列表, 或者指定動態inventory腳本
module_name='ping', # 模塊名
module_args='', # 模塊參數
extra_vars={"ansible_ssh_user":"root","ansible_ssh_pass":"xx"},
forks=10
)
datastructure = runner.run()
data = json.dumps(datastructure,indent=4)
2.0 之後的調用
import json
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor
loader = DataLoader() # 用來加載解析yaml文件或JSON內容,並且支持vault的解密
variable_manager = VariableManager() # 管理變量的類,包括主機,組,擴展等變量,之前版本是在 inventory 中的
inventory = Inventory(loader=loader, variable_manager=variable_manager)
variable_manager.set_inventory(inventory) # 根據 inventory 加載對應變量
class Options(object):
'''
這是壹個公***的類,因為ad-hoc和playbook都需要壹個options參數
並且所需要擁有不同的屬性,但是大部分屬性都可以返回None或False
因此用這樣的壹個類來省去初始化大壹堆的空值的屬性
'''
def __init__(self):
self.connection = "local"
self.forks = 1
self.check = False
def __getattr__(self, name):
return None
options = Options()
def run_adhoc():
variable_manager.extra_vars={"ansible_ssh_user":"root" , "ansible_ssh_pass":"xxx"} # 增加外部變量
# 構建pb, 這裏很有意思, 新版本運行ad-hoc或playbook都需要構建這樣的pb, 只是最後調用play的類不壹樣
# :param name: 任務名,類似playbook中tasks中的name
# :param hosts: playbook中的hosts
# :param tasks: playbook中的tasks, 其實這就是playbook的語法, 因為tasks的值是個列表,因此可以寫入多個task
play_source = {"name":"Ansible Ad-Hoc","hosts":"10.10.0.1","gather_facts":"no","tasks":[{"action":{"module":"shell","args":"w"}}]}
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=None,
stdout_callback='minimal',
run_tree=False,
)
result = tqm.run(play)
print result
finally:
if tqm is not None:
tqm.cleanup()
if __name__ == '__main__':
run_adhoc()
Playbook
playbook 則類似於 SaltStack 中的 state
2.0 之前的調用
from ansible import callbacks
from ansible import utils
from ansible.playbook import PlayBook
stats = callbacks.AggregateStats()
callback = callbacks.PlaybookCallbacks()
runner_callbacks = callbacks.PlaybookRunnerCallbacks(stats)
pb = ansible.playbook.PlayBook(
playbook="tasks.yml",
stats=stats,
callbacks=playbook_cb,
runner_callbacks=runner_cb,
check=True
)
pb.run()
2.0 之後的調用
import json
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.executor.playbook_executor import PlaybookExecutor
loader = DataLoader() # 用來加載解析yaml文件或JSON內容,並且支持vault的解密
variable_manager = VariableManager() # 管理變量的類,包括主機,組,擴展等變量,之前版本是在 inventory 中的
inventory = Inventory(loader=loader, variable_manager=variable_manager)
variable_manager.set_inventory(inventory) # 根據 inventory 加載對應變量
class Options(object):
'''
這是壹個公***的類,因為ad-hoc和playbook都需要壹個options參數
並且所需要擁有不同的屬性,但是大部分屬性都可以返回None或False
因此用這樣的壹個類來省去初始化大壹堆的空值的屬性
'''
def __init__(self):
self.connection = "local"
self.forks = 1
self.check = False
def __getattr__(self, name):
return None
options = Options()
def run_playbook():
playbooks=['task.yaml'] # 這裏是壹個列表, 因此可以運行多個playbook
variable_manager.extra_vars={"ansible_ssh_user":"root" , "ansible_ssh_pass":"xxx"} # 增加外部變量
pb = PlaybookExecutor(playbooks=playbooks, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=None)
result = pb.run()
print result
if __name__ == '__main__':
run_playbook()