■ はじめに
Ansible には、IP アドレスに対してさまざまフィルターをかける ipaddrというフィルタープラグインがあります。
このフィルターを使って、プレフィックス表記とネットマスク表記を相互に変換する方法をまとまめす。
- プレフィックス表記からネットマスク表記
- 例: 172.16.1.1/24 → 172.16.1.1/255.255.255.0
- ネットマスク表記からプレフィックス表記
- 例: 172.16.1.1/255.255.255.0 → 172.16.1.1/24
ipaddr('netmask')
でネットマスクを、ipaddr('prefix')
でプレフィックスを取得するのがポイントです。
- 動作確認環境: Ansible 2.8.4
- 要 netaddr (
pip install netaddr
でインストール)
■ フィルターの書き方
プレフィックス表記からネットマスク表記
"{{ '172.16.1.1/24' | replace(item | ipaddr('prefix'), '') }}{{ item | ipaddr('netmask') }}"
変換後: 172.16.1.1/255.255.255.0
ホストアドレスにもネットワークアドレスにも対応させるために、少々まどろこっしい書き方になっています。
本当は、ipaddr
フィルターで直接 172.16.1.1/24
を 172.16.1.1
にしてからネットマスクを付加したかったのですが、コードを見てもやり方が見つかりませんでした。そのため、まず replace
でプレフィックスを削除しています。
なお、スラッシュ区切りではなく、スペース区切りで良ければ以下のようにシンプルなフィルターでOKです。
"{{ '172.16.1.1/24' | ipaddr('ip_netmask') }}"
変換後: 172.16.1.1 255.255.255.0
ただし、ネットワークアドレスをフィルタすると空になってしまうので、以下のようにする必要があります。
"{{ '172.16.1.0/24' | ipaddr('network_netmask') }}"
変換後: 172.16.1.0 255.255.255.0
ネットマスク表記からプレフィックス表記
"{{ '172.16.1.1/255.255.255.0' | replace(item | ipaddr('netmask'), '') }}{{ item | ipaddr('prefix') }}"
変換後: 172.16.1.1/24
少々まどろっこしくなっているのは前述の事情のとおりです。
なお、ホストアドレスだけが対象であれば、以下のようにシンプルなフィルターでOKです。
"{{ '172.16.1.1/255.255.255.0' | ipaddr('ip/prefix') }}"
変換後: 172.16.1.1/24
ネットワークアドレスだけが対象であれば、以下のとおりです。
"{{ '172.16.1.0/255.255.255.0' | ipaddr('network/prefix') }}"
変換後: 172.16.1.0/24
■ サンプル
いくつかインプットのパターンを用意した Playbook で試します。
Playbook
Playbook はこちらです。
- netconv.yml
- hosts: localhost gather_facts: no connection: local tasks: - name: prefix > netmask debug: msg: "{{ item | replace(item | ipaddr('prefix'), '') }}{{ item | ipaddr('netmask') }}" loop: - 172.16.1.0/24 # ネットワークアドレス - 172.16.1.1/24 - 172.16.1.254/24 - 172.16.1.255/24 # ブロードキャストアドレス - name: mask > netprefix debug: msg: "{{ item | replace(item | ipaddr('netmask'), '') }}{{ item | ipaddr('prefix') }}" loop: - 172.16.1.0/255.255.255.0 # ネットワークアドレス - 172.16.1.1/255.255.255.0 - 172.16.1.254/255.255.255.0 - 172.16.1.255/255.255.255.0 # ブロードキャストアドレス
実行結果
実行します。
$ ansible-playbook -i localhost, netconv.yml
(抜粋)
TASK [prefix > netmask] *********************************** ok: [localhost] => (item=172.16.1.0/24) => { "msg": "172.16.1.0/255.255.255.0" } ok: [localhost] => (item=172.16.1.1/24) => { "msg": "172.16.1.1/255.255.255.0" } ok: [localhost] => (item=172.16.1.254/24) => { "msg": "172.16.1.254/255.255.255.0" } ok: [localhost] => (item=172.16.1.255/24) => { "msg": "172.16.1.255/255.255.255.0" } TASK [mask > netprefix] *********************************** ok: [localhost] => (item=172.16.1.0/255.255.255.0) => { "msg": "172.16.1.0/24" } ok: [localhost] => (item=172.16.1.1/255.255.255.0) => { "msg": "172.16.1.1/24" } ok: [localhost] => (item=172.16.1.254/255.255.255.0) => { "msg": "172.16.1.254/24" } ok: [localhost] => (item=172.16.1.255/255.255.255.0) => { "msg": "172.16.1.255/24" }
■ まとめ
ipaddr フィルタープラグインを使って、プレフィックス表記とネットマスク表記を相互に変換する方法をまとめました。ipaddr フィルタープラグインには、他にもさまざまな機能がありますので、IP アドレスに対してなにか加工したい場合は、このフィルターを調べてみると良いかもしれません。
※ もっと良い方法をご存知の方、@akira6592 までご連絡いただけると幸いです。
参考
- ipaddr フィルタープラグインのコード
- https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/filter/ipaddr.py
- ドキュメントに載っていない
ipaddr('network_netmask')
などの書き方も読み解ける
- ipaddr フィルタープラグインが内部で利用している Python ライブラリ
netaddr