【Ansible】ソートされたリストの並び順をチェックする方法
【結論】
- Pythonであれば
index()
でリストの添字を取得できるので簡単に比較できる。 - 同じことをAnsibleでも実装したかったのですが、いくら探してもPythonの
index()
に相当する書き方を見つけることができませんでした。 - よって、苦肉の索として辞書型に変換して比較することにしました。
- 本記事で紹介する書き方より良いAnsibleの書き方をご存知の方は教えて欲しいです。
【目次】
はじめに
現在業務でAnsibleを使ってファイアウォールの設定を自動で行うプレイブックの開発を行っています。
ファイアウォールにポリシーを追加して並び替える部分はAPIを叩いて実装できたのですが、ポリシーが意図通りに並び変わっていることを確認する処理の実装にかなり手間取ったのでブログにまとめました。
前提条件
Ansibleでソートされたリストの並び順をチェックする方法の解説がメインであるため、ファイアウォールやAPIを叩いてポリシーを取得する方法についての説明は省略します。
ポリシーの一覧は既に優先度の高い順にリストに格納されているものとします。
pythonの場合
policy_list = ["red", "green", "aaaa", "yellow", "purple"]
Ansibleの場合
- set_fact: policy_list: ["red", "green", "aaaa", "yellow", "purple"]
Pythonで書いた場合
policy_check()
ではリストの要素のインデックス(何番目か)を取得して比較しています。
これが一般的な実装方法だと思われます。
しかし、policy_check_yml()
ではリスト型をわざわざ辞書型に変換してから、優先度を比較しています。
理由は、Ansibleでindex()
に相当するモジュールを見つけれなかったので、苦肉の策として辞書型に変換して書いた処理を解説するためにPythonでも書いています。
ソース(.py)
def policy_check(policy_list, base_policy, sorted_policy): # ポリシーの優先度チェック1 if policy_list.index(base_policy) < policy_list.index(sorted_policy): print(f"優先度高:{base_policy}") else: # ポリシーの優先度チェック2 print(f"優先度高:{sorted_policy}") def policy_check_yml(policy_list, base_policy, sorted_policy): # ポリシーリストを辞書型に変換 rank_dic = {} for i,v in enumerate(policy_list): rank_dic[v] = i # ポリシーの優先度チェック1 if rank_dic[base_policy] < rank_dic[sorted_policy]: print(f"優先度高:{base_policy}") else: # ポリシーの優先度チェック2 print(f"優先度高:{sorted_policy}") def main(): # 変数初期化 policy_list = ["red", "green", "aaaa", "yellow", "purple"] base_policy = "aaaa" sorted_policy = "green" # Pythonde書く場合 policy_check(policy_list, base_policy, sorted_policy) # Ansibleの実装をPythonに置き換えた場合 policy_check_yml(policy_list, base_policy, sorted_policy) main()
実行結果
優先度高:green 優先度高:green
Ansibleで書いた場合
かなり強引に書いている自覚はあります。
ソース(.yml)
--- - hosts: localhost # 自分自身に接続する tasks: - naeme: 変数初期化 set_fact: base_policy: "aaaa" sorted_policy: "green" policy_list: ["red", "green", "aaaa", "yellow", "purple"] num_id: 1 - name: ポリシーリストを辞書型に変換 set_fact: num_id: "{{(num_id|int) + (1|int)}}" rank_dic: "{{ rank_dic | default({}) | combine( {item: num_id} ) }}" with_items: "{{ policy_list }}" - debug: msg="{{rank_dic}}" - name: ポリシーの優先度チェック1 debug: msg="優先度高:{{base_policy}}" when: rank_dic[base_policy] < rank_dic[sorted_policy] - name: ポリシーの優先度チェック2 debug: msg="優先度高:{{sorted_policy}}" when: rank_dic[base_policy] > rank_dic[sorted_policy]
実行結果
💩コードを撲滅するために...
以下のような「俺ならこう書くぜ」的なのが出てくるのを期待してます🥺
jsonであれば vars_files で直接読み込めるので、こんなので行ける気も・・! pic.twitter.com/ogAlBWCHql
— よこち(yokochi) (@akira6592) 2019年7月13日
参考情報
Python, enumerateの使い方: リストの要素とインデックスを取得 | note.nkmk.me
さいごに
Aさん:「なんで、配布されているディスプレイを使わないんですか?」
Bさん:「谷に落ちても大丈夫なように、普段から鍛えているんです。」
Aさん:「なるほどww。ひどいところは、ノートPCだけでマウスすら配布されないですからね。」
職場でこんな会話が聞こえてきて、笑ってしまった🤣