Overview
ただし、こちらの記事の記載の通り既存のplaybookが完成している場合、
互換性がないので使えない。
python nativeで最初から作るならば問題ないが、
既にAnsibleで作ってしまった環境を徐々に移行していくためには
当面、ansible-playbookを実行する必要がある。
従ってpython native コードに求められる機能は主に二つ。
- ansible-playbook を読み込める(実行できる)
- 既存のレシピを実行する為
- ansible-playbook を生成できる
- 完全に移行するまでは ansile-playbook... の実行も続くため
どうやってansible-playbookを実行するか
perl の systemみたいに ansible-playbook xxxx としてシェルを呼ぶのでは意味が無い。
ちゃんとpythonから呼ぶ必要がある
どうやら ansible playbook-executor を使えば良いようだ。
具体的には以下の部分。
play_sourceを定義し、TQMを用いた場合と異なり
PlaybookExecutor に渡すことで、ansible-playbookコマンドを実行した通りの動作になる。
resultや出力の制御を行っていないがその辺はおいおい。
pbex = PlaybookExecutor(
playbooks=[playbook_path],
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords
)
results = pbex.run()
taskを直接記述する場合
play_source = dict(
name="Ansible Play",
hosts=['localhost'],
gather_facts='no',
tasks=[dict(action=dict(
module='command',
args=dict(cmd='/usr/bin/uptime')
))]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
tqm = None
results_callback = ResultCallback()
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords,
stdout_callback=results_callback,
)
2018.10.29 追記
以下のようにPlaybookExecutor
の._tqm._stdout_callback
をフックしてやれば拾えた。
既存サンプルを更新しても良いが比較できるように
ansible-runner_callback.py として commit しました。
class ResultCallback(CallbackBase):
def __init__(self, *args, **kwargs):
super(ResultCallback, self).__init__(*args, **kwargs)
self.host_ok = {}
self.host_unreachable = {}
self.host_failed = {}
def v2_runner_on_unreachable(self, result):
super(ResultCallback, self).v2_runner_on_unreachable(result)
print(json.dumps({result._host.name: result._result}, indent=4))
def v2_runner_on_ok(self, result, **kwargs):
super(ResultCallback, self).v2_runner_on_ok(result)
print(json.dumps({result._host.name: result._result}, indent=4))
def v2_runner_on_failed(self, result, *args, **kwargs):
super(ResultCallback, self).v2_runner_on_failed(result)
print(json.dumps({result._host.name: result._result}, indent=4))
executor = PlaybookExecutor(
playbooks=[playbook_path],
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords
)
results_callback = ResultCallback()
executor._tqm._stdout_callback = results_callback
results = executor.run()
サンプルスクリプト
- 以下に置いた。説明などは今後追加する
- https://github.com/ainamori/python-ansible