この記事はアドベントカレンダーの20日目の記事です
はじめに
最近showコマンドの結果をパースして、パースした結果をこねくり回すことが増えてきました。 そんな中で、特定のKeyのみを残す、特定のKeyを削除する必要があり自作フィルタを使っていました 。
ansible.utils 2.5.0(2022-01-31リリース)から追加されたxxx_keys系のフィルタが自分が作っていたものとほぼ同じ動きをするフィルタだったので動作確認をして置き換えましたので紹介します。
昨年の記事で試したrouteのDiffをとる前に、データ操作としてJinja2テンプレートをいじったり、カスタムフィルタを使ったりしましたが、別解のようなイメージです。
keep_keysフィルタ
文字通り、指定されたKeyのみを保持するフィルタです
サンプルプレイブック
--- - hosts: localhost gather_facts: false vars: routes: - network: "195.0.0.0" distance: "110" mask: "24" metric: "11" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "IA" uptime: "00:05:45" - network: "0.0.0.0" distance: "110" mask: "0" metric: "1" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "E2" uptime: "00:05:35" tasks: - name: keep_keys ansible.builtin.debug: msg: "{{ routes | ansible.utils.keep_keys(target=['network','distance']) }}"
フィルタの変数targetにリストで渡した文字列のKeyのみを保持します
targerはregrexやstarts_with/ends_withなど正規表現を使ってマッチさせることも可能です
keep_keys(target=['^ne','distance'], matching_parameter= 'starts_with')
実行結果
TASK [keep_keys] ************************************************************************************************************************ ok: [localhost] => { "msg": [ { "distance": "110", "network": "195.0.0.0" }, { "distance": "110", "network": "0.0.0.0" } ] }
targetsに指定したnetwork/distanceのみのデータに整形できました
remove_keysフィルタ
こちら指定したキーを削除するフィルタになります
uptimeを取り除く例
--- - hosts: localhost gather_facts: false vars: routes: - network: "195.0.0.0" distance: "110" mask: "24" metric: "11" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "IA" uptime: "00:05:45" - network: "0.0.0.0" distance: "110" mask: "0" metric: "1" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "E2" uptime: "00:05:35" tasks: - name: remove_keys ansible.builtin.debug: msg: "{{ routes | ansible.utils.remove_keys(target=['uptime']) }}"
keep_keysフィルタと同様に変数targetにリストで渡します
matching_parameterも同様に利用可能です
出力
TASK [remove_keys] ************************************************************************************************************************* ok: [localhost] => { "msg": [ { "distance": "110", "mask": "24", "metric": "11", "network": "195.0.0.0", "nexthop_if": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "IA" }, { "distance": "110", "mask": "0", "metric": "1", "network": "0.0.0.0", "nexthop_if": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "E2" } ] }
フィルタにかけた後のデータからuptimeが消えたことが確認できます
replace_keysフィルタ
replace_keysフィルタはKeyの名前を変えることができるフィルタです
--- - hosts: localhost gather_facts: false vars: routes: - network: "195.0.0.0" distance: "110" mask: "24" metric: "11" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "IA" uptime: "00:05:45" - network: "0.0.0.0" distance: "110" mask: "0" metric: "1" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "E2" uptime: "00:05:35" tasks: - name: replace_keys ansible.builtin.debug: msg: "{{ routes | ansible.utils.replace_keys(target=[{'before':'nexthop_if', 'after':'nexthop_interface'}]) }}"
フィルタの変数targetsには[{before: XXX, after: XXXZ}]とどのKeyを何に変えるかを定義する必要があります
matching_parameterはkeep_keys/remove_keysと同様に利用可能です
nexthop_ifのKeyをnexthop_interfaceに変更します。
出力
TASK [replace_keys] ********************************************************************************************************************* ok: [localhost] => { "msg": [ { "distance": "110", "mask": "24", "metric": "11", "network": "195.0.0.0", "nexthop_interface": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "IA", "uptime": "00:05:45" }, { "distance": "110", "mask": "0", "metric": "1", "network": "0.0.0.0", "nexthop_interface": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "E2", "uptime": "00:05:35" } ] }
nexthop_ifをnexthop_interfaceに変更できました。
まとめ
ansible.utilsの3つのフィルタを紹介しました
コレクションで提供されている便利なフィルタは積極的に使っていきたいですね。
ちなみに
書いてる時に思い出しましたがすべて、json_queryでもできますね笑
--- - hosts: localhost gather_facts: false vars: routes: - network: "195.0.0.0" distance: "110" mask: "24" metric: "11" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "IA" uptime: "00:05:45" - network: "0.0.0.0" distance: "110" mask: "0" metric: "1" nexthop_if: "FastEthernet0/0.100" nexthop_ip: "194.0.0.2" protocol: "O" type: "E2" uptime: "00:05:35" tasks: - name: json_query(keep_keys) ansible.builtin.debug: msg: "{{ routes | community.general.json_query(query_string) }}" vars: query_string: "[*].{network: network, distance: distance}" - name: json_query(remove_keys) ansible.builtin.debug: msg: "{{ routes | community.general.json_query(query_string) }}" vars: query_string: "[*].{network: network, distance: distance, mask: mask, metric: metric, nexthop_if: nexthop_if, nexthop_ip: nexthop_ip, protocol: protocol, type: type}" - name: json_query(replace_keys) ansible.builtin.debug: msg: "{{ routes | community.general.json_query(query_string) }}" vars: query_string: "[*].{network: network, distance: distance, mask: mask, metric: metric, nexthop_interface: nexthop_if, nexthop_ip: nexthop_ip, protocol: protocol, type: type}"
実行結果
TASK [json_query(keep_keys)] *************************************************************************************************************** ok: [localhost] => { "msg": [ { "distance": "110", "network": "195.0.0.0" }, { "distance": "110", "network": "0.0.0.0" } ] } TASK [json_query(remove_keys)] ************************************************************************************************************** ok: [localhost] => { "msg": [ { "distance": "110", "mask": "24", "metric": "11", "network": "195.0.0.0", "nexthop_if": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "IA" }, { "distance": "110", "mask": "0", "metric": "1", "network": "0.0.0.0", "nexthop_if": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "E2" } ] } TASK [json_query(replace_keys)] *************************************************************************************************************** ok: [localhost] => { "msg": [ { "distance": "110", "mask": "24", "metric": "11", "network": "195.0.0.0", "nexthop_interface": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "IA" }, { "distance": "110", "mask": "0", "metric": "1", "network": "0.0.0.0", "nexthop_interface": "FastEthernet0/0.100", "nexthop_ip": "194.0.0.2", "protocol": "O", "type": "E2" } ] }