當前位置:首頁 » 操作系統 » ansible源碼

ansible源碼

發布時間: 2023-06-07 02:33:27

① 如何使用Ansible 2的API做python開發

在ansible1.9的時候,API是一個非常簡單的東西。官方說「it's pretty simple」,真是又pretty又simple。

import ansible.runner

runner = ansible.runner.Runner(
mole_name='ping',
mole_args='',
pattern='web*',
forks=10
)
datastructure = runner.run()

到了ansible2.0以後,是「a bit more complicated」,Oh my,簡直讓人難受。

簡潔和靈活是魚和熊掌。

ansible2.0 API怎麼用?

ansible2.0更貼近於ansible cli的常用命令執行方式,不同於上一版本只能發送單個命令或playbook;而更推薦用戶在調用ansibleAPI的時候,將playbook的每個task拆分出來,獲取每個task的結果。能夠跟靈活處理在執行批量作業過程中的各種反饋。

將執行操作的隊列模型,包含各類環境參數設置,歸結到「ansible.executor.task_queue_manager」類中

將執行過程中的各個task的設置,或者說playbook中的編排內容,歸結到「ansible.playbook.play」中

上述兩個東西,幾乎囊括了可以在執行過程中設置的所有參數,足夠靈活,也讓人抓狂,相當於需要自己寫一個1.9版本中的runner。
他們的確也都是原生類,並非專用於外部調用。

ansible.executor.task_queue_manager

這是ansible的一個內部模塊(ansible/executor/task_queue_manager.py)。初始化的源碼如下:

class TaskQueueManager:

'''
This class handles the multiprocessing requirements of Ansible by
creating a pool of worker forks, a result handler fork, and a
manager object with shared datastructures/queues for coordinating
work between all processes.

The queue manager is responsible for loading the play strategy plugin,
which dispatches the Play's tasks to hosts.
'''

def __init__(self, inventory, variable_manager, loader, options, passwords, stdout_callback=None, run_additional_callbacks=True, run_tree=False):

self._inventory = inventory
self._variable_manager = variable_manager
self._loader = loader
self._options = options
self._stats = AggregateStats()
self.passwords = passwords
self._stdout_callback = stdout_callback
self._run_additional_callbacks = run_additional_callbacks
self._run_tree = run_tree

self._callbacks_loaded = False
self._callback_plugins = []
self._start_at_done = False
self._result_prc = None

……

創建時,需要的主要參數包括:

inventory --> 由ansible.inventory模塊創建,用於導入inventory文件

variable_manager --> 由ansible.vars模塊創建,用於存儲各類變數信息

loader --> 由ansible.parsing.dataloader模塊創建,用於數據解析

options --> 存放各類配置信息的數據字典

passwords --> 登錄密碼,可設置加密信息

stdout_callback --> 回調函數

ansible.playbook.play

ansible.playbook是一個原生模塊,既用於CLI也用於API。從源碼可以看出來:

try:
from __main__ import display
except ImportError:
from ansible.utils.display import Display
display = Display()

ansible.playbook.play(ansible/playbook/play.py)。初始化源碼的介紹如下:

__all__ = ['Play']

class Play(Base, Taggable, Become):

"""
A play is a language feature that represents a list of roles and/or
task/handler blocks to execute on a given set of hosts.

Usage:

Play.load(datastructure) -> Play
Play.something(...)
"""

最後,用task_queue_manager(play)來執行,老規矩,源碼的官方解釋。

def run(self, play):
'''
Iterates over the roles/tasks in a play, using the given (or default)
strategy for queueing tasks. The default is the linear strategy, which
operates like classic Ansible by keeping all hosts in lock-step with
a given task (meaning no hosts move on to the next task until all hosts
are done with the current task).
'''

一個完整的例子

# -*- coding:utf-8 -*-
# !/usr/bin/env python
#
# Author: Shawn.T
# Email: [email protected]
#
# this is the Interface package of Ansible2 API
#

from collections import namedtuple
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 tempfile import NamedTemporaryFile
import os

class AnsibleTask(object):
def __init__(self, targetHost):
Options = namedtuple(
'Options', [
'listtags', 'listtasks', 'listhosts', 'syntax', 'connection','mole_path',
'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args',
'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user',
'verbosity', 'check'
]
)

# initialize needed objects
self.variable_manager = VariableManager()

self.options = Options(
listtags=False, listtasks=False, listhosts=False, syntax=False, connection='smart',
mole_path='/usr/lib/python2.7/site-packages/ansible/moles', forks=100,
remote_user='root', private_key_file=None, ssh_common_args=None, ssh_extra_args=None,
sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user='root',
verbosity=None, check=False
)
self.passwords = dict(vault_pass='secret')
self.loader = DataLoader()

# create inventory and pass to var manager
self.hostsFile = NamedTemporaryFile(delete=False)
self.hostsFile.write(targetHost)
self.hostsFile.close()
self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.hostsFile.name)
self.variable_manager.set_inventory(self.inventory)

def ansiblePlay(self, action):
# create play with tasks
args = "ls /"
play_source = dict(
name = "Ansible Play",
hosts = 'all',
gather_facts = 'no',
tasks = [
dict(action=dict(mole='shell', args=args), register='shell_out'),
dict(action=dict(mole='debug', args=dict(msg='{{shell_out.stdout}}')))
]
)
play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)

# run it
tqm = None
try:
tqm = TaskQueueManager(
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
options=self.options,
passwords=self.passwords,
stdout_callback='default',
)
result = tqm.run(play)
finally:
# print result
if tqm is not None:
tqm.cleanup()
os.remove(self.hostsFile.name)
self.inventory.clear_pattern_cache()
return result

寫一個ansibleTask類,創建了上述的各類必要的配置信息對象,最後使用ansibleTask.ansiblePlay()函數執行。

inventory文件的動態生成

寫上面的代碼的過程中,碰到一個問題:inventory對象創建時需要一個實體的hosts文件,而文件需要動態生成。
生成的方法參考了這篇牛逼閃閃的文章。使用tempfile.NamedTemporaryFile這個方法來創建一個有名稱的臨時文件,可以選擇關閉後刪除或保留。上面的處理辦法是:不刪除,在執行完畢之後,通過os.remove(self.hostsFile.name)進行刪除。

ps.經YiChenWang指出,inventory的創建參數host_list可以使列表。使用以下方式創建inventory也是可以的:

self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=['xx.xx.xx.xx', 'xx.xx.xx.xx'])

不過,源碼中指出,採用list格式參數是無法載入inventory data的。如果需要載入,還是得使用臨時文件的辦法。

熱點內容
scratch少兒編程課程 發布:2025-04-16 17:11:44 瀏覽:626
榮耀x10從哪裡設置密碼 發布:2025-04-16 17:11:43 瀏覽:356
java從入門到精通視頻 發布:2025-04-16 17:11:43 瀏覽:71
php微信介面教程 發布:2025-04-16 17:07:30 瀏覽:296
android實現陰影 發布:2025-04-16 16:50:08 瀏覽:787
粉筆直播課緩存 發布:2025-04-16 16:31:21 瀏覽:337
機頂盒都有什麼配置 發布:2025-04-16 16:24:37 瀏覽:202
編寫手游反編譯都需要學習什麼 發布:2025-04-16 16:19:36 瀏覽:798
proteus編譯文件位置 發布:2025-04-16 16:18:44 瀏覽:355
土壓縮的本質 發布:2025-04-16 16:13:21 瀏覽:582