この投稿はAnsible 3 Advent Calendar 2019の2日目の記事です。
別々のリストにある辞書で共通キーがあるものを結合したいという時があったりなかったりあったりします。
その時のフィルター例です。
ここではシーケンスをリスト、マッピングを辞書と表現します
変数ファイル
ここでは次のファイルに定義した変数を使用します。
demon_slayer1.yml
---
damon_slayer:
- organization: 鬼殺隊
calacters:
- name: 竈門炭治郎
sword_color: 黒
- name: 嘴平伊之助
sword_color: 藍鼠
- name: 我妻善逸
sword_color: 黄色
demon_slayer2.yml
---
damon_slayer:
- organization: 鬼殺隊
calacters:
- name: 竈門炭治郎
words:
- 頑張れ!人は心が原動力だから心はどこまでも強くなれる!
- 頑張れ炭治郎頑張れ!俺は今までよくやってきた!俺はできる奴だ!
- 水の呼吸 壱ノ型 水面斬り
- name: 嘴平伊之助
words:
- 猪突猛進!
- ゴメンネ弱クッテ
- 獣の呼吸 壱ノ牙 穿ち抜き
- name: 我妻善逸
words:
- こんなことある!?
- 禰󠄀豆子ちゃんは俺がまもる
- 雷の呼吸 壱ノ型 霹靂一閃
- name: 竈門禰󠄀豆子
words:
- ''
両方の変数にある同じ organization
内にある name
を共通キーにし、共通キーにマッチしたら辞書を結合するということをします。
Playbook
Playbookはこんな感じです。
---
- name: ni no kata playbook
hosts: localhost
gather_facts: no
tasks:
- name: include vars from daemon_slayer1.yml
include_vars: demon_slayer1.yml
- name: set daemon_slayer1 variable
set_fact:
daemon_slayer1: "{{ damon_slayer }}"
- name: include vars from daemon_slayer2.yml
include_vars: demon_slayer2.yml
- name: set daemon_slayer2 variable
set_fact:
daemon_slayer2: "{{ damon_slayer }}"
- debug:
msg: >-
{{ [item.1]
| selectattr("name", "equalto", item.1.name)
| list
| first
| combine(data.0 | default({}))
}}
vars:
data: >-
{{ daemon_slayer1
| selectattr("organization", "equalto", item.0.organization)
| map(attribute="calacters")
| list
| first
| selectattr("name", "equalto", item.1.name)
| list
}}
with_subelements:
- "{{ daemon_slayer2 }}"
- calacters
data
変数には daemon_slayer2
を with_subelements
で回し daemon_slayer1
の organization
とマッチしたら次に calacters
から同じ name
を見つけます。
そして、次は daemon_slayer2
の calacters
を元に data
に使った name
と共通する辞書を抜き出して結合します。
default({})
があるのは daemon_slayer1
には禰󠄀豆子ちゃんがいないので、その対策です。
Playbook実行
これを実行します。
(venv) [root@localhost ansible]# ansible-playbook main.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [ni no kata playbook] ****************************************************************************************************************************************************
TASK [include vars from daemon_slayer1.yml] ***********************************************************************************************************************************
ok: [localhost]
TASK [set daemon_slayer1 variable] ********************************************************************************************************************************************
ok: [localhost]
TASK [include vars from daemon_slayer2.yml] ***********************************************************************************************************************************
ok: [localhost]
TASK [set daemon_slayer2 variable] ********************************************************************************************************************************************
ok: [localhost]
TASK [debug] ******************************************************************************************************************************************************************
ok: [localhost] => (item=[{'organization': '鬼殺隊'}, {'name': '竈門炭治郎', 'words': ['頑張れ!人は心が原動力だから心はどこまでも強くなれる!', '頑張れ炭治郎頑張れ!俺は今までよくやってきた!俺はできる奴だ!', '水の呼吸 壱ノ型 水面斬り']}]) => {
"msg": {
"name": "竈門炭治郎",
"sword_color": "黒",
"words": [
"頑張れ!人は心が原動力だから心はどこまでも強くなれる!",
"頑張れ炭治郎頑張れ!俺は今までよくやってきた!俺はできる奴だ!",
"水の呼吸 壱ノ型 水面斬り"
]
}
}
ok: [localhost] => (item=[{'organization': '鬼殺隊'}, {'name': '嘴平伊之助', 'words': ['猪突猛進!', 'ゴメンネ弱クッテ', '獣の呼吸 壱ノ牙 穿ち抜き']}]) => {
"msg": {
"name": "嘴平伊之助",
"sword_color": "藍鼠",
"words": [
"猪突猛進!",
"ゴメンネ弱クッテ",
"獣の呼吸 壱ノ牙 穿ち抜き"
]
}
}
ok: [localhost] => (item=[{'organization': '鬼殺隊'}, {'name': '我妻善逸', 'words': ['こんなことある!?', '禰󠄀豆子ちゃんは俺がまもる', '雷の呼吸 壱ノ型 霹靂一閃']}]) => {
"msg": {
"name": "我妻善逸",
"sword_color": "黄色",
"words": [
"こんなことある!?",
"禰󠄀豆子ちゃんは俺がまもる",
"雷の呼吸 壱ノ型 霹靂一閃"
]
}
}
ok: [localhost] => (item=[{'organization': '鬼殺隊'}, {'name': '竈門禰󠄀豆子', 'words': ['']}]) => {
"msg": {
"name": "竈門禰󠄀豆子",
"words": [
""
]
}
}
PLAY RECAP ********************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
共通 name
キーおよび片方には存在しない辞書の結合できました :)