Ansible使おうとしたら名前付きパイプ(makefifo
)相当がなかったので自作モジュールを頑張ることにした。
参考サイト
-
Ansibleのモジュール開発(Python実装編)
- すっごい分かりやすくて好き!
-
ansible コマンドでモジュール引数 ( パラメータ ) を複数渡す方法
-
ansible
コマンド実行時に複数の引数を与える方法
-
環境
$ cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
$ ansible --version
ansible 2.9.7
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/ansi/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
雛形を作る
参考サイトを見つつ
makefifo.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from ansible.module_utils.basic import AnsibleModule
module = AnsibleModule(
dict=(
message=dict()
)
)
print '{"message_key":"%s"}' % (module.params['message'])
んーとこんな感じでいいのかなぁ~。早速実行してみよう。
$ ansible -i test_grp 192.168.56.104 -m makefifo -M library -u root -a message=test
192.168.56.104 | FAILED! => {
"msg": "Unable to import makefifo due to invalid syntax"
}
OOPS!! あれれ。。いきなり躓いたぞい。
Ansibleのバージョンによって差分があるのかな?ということで既存のモジュールを解体して作ってみようと方向シフト。
$ find /usr/lib/python2.7/site-packages -type f -name ping.py
/usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
コイツをコピってきてpong.py
にリネームしてまずは正常動作確認。
$ ansible -i test_grp 192.168.56.104 -m pong -M library -u root -a data=hoge
192.168.56.104 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "hoge"
}
うん、動いてる。
ココから中身の要らなさそうな部分を削ってみた結果、以下まで削ることができた。
pong.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from ansible.module_utils.basic import AnsibleModule
# メイン処理
#-----------------------------------------------------------
def main():
# AnsibleModuleクラス: moduleを作成
module = AnsibleModule(
# 引数受け取り
argument_spec=dict(
# 引数: data(str型,def:pong)
data=dict(type='str', default='pong'),
),
# 引数チェックを有効
supports_check_mode=True
)
# 結果dict: resultを作成
result = dict(
# key: ping に引数で与えられたkey: data のvalueを格納
ping=module.params['data'],
)
# resultの中身を key=value,の形で出力
module.exit_json(**result)
if __name__ == '__main__':
main()
$ ansible -i test_grp 192.168.56.104 -m pong -M library -u root -a data=hoge
192.168.56.104 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "hoge"
}
コイツを雛形にしよう。
引数を受け取る
makefifo
に必要なパラメータは以下かなと考える。
パラメータ | 変数名(key名) | 型 | 必須 |
---|---|---|---|
ファイルパス | path | str | ○ |
所有者(ユーザ) | owner | str | ○ |
所有者(グループ) | group | str | ○ |
パーミッション | mode | str | ○ |
まずはコイツらを受け取っって結果に返すだけのモジュールを作ってみる。
makefifo.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from ansible.module_utils.basic import AnsibleModule
# メイン処理
#-----------------------------------------------------------
def main():
# AnsibleModuleクラス: moduleを作成
module = AnsibleModule(
# 引数受け取り
argument_spec=dict(
# 引数: path(str型, 必須)
path=dict(type='str', required=True),
# 引数: owner(str型, 必須)
owner=dict(type='str', required=True),
# 引数: group(str型, 必須)
group=dict(type='str', required=True),
# 引数: mode(str型, 必須)
mode=dict(type='str', required=True),
),
# 引数チェックを有効
supports_check_mode=True
)
# 結果dict: resultを作成
result = dict(
path=module.params['path'],
owner=module.params['owner'],
group=module.params['group'],
mode=module.params['mode'],
)
# resultの中身を key=value,の形で出力
module.exit_json(**result)
if __name__ == '__main__':
main()
required
とかそのあたりはAnsibleのモジュール開発(Python実装編)さんを参考に。
さて動作確認...複数の引数を与えるのはどうするんだ?で調べたら以下が見つかった。
ありがてぇありがてぇ。
$ ansible -i test_grp 192.168.56.104 -m makefifo -M library -u root -a "path=/tmp/hoge owner=root group=root mode=0644"
192.168.56.104 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/tmp/hoge"
}
できた!よしよし、あとはPython
で実装するだけだな。
取り敢えず今日はココまで。