web-dev-qa-db-ja.com

Ansible:リストを属性でフィルタリングする

Ansibleに登録されている「network」という名前の変数があります。

{
    "addresses": {
        "private_ext": [
            {
                "type": "fixed",
                "addr": "172.16.2.100"
            }
        ],
        "private_man": [
            {
                "type": "fixed",
                "addr": "172.16.1.100"
            },
            {
                "type": "floating",
                "addr": "10.90.80.10"
            }
        ]
    }
}

Type = "floating"でIPアドレス( "addr")を取得することは可能ですか?

- debug: var={{ network.addresses.private_man | filter type="fixed" | get "addr" }}

私は構文が間違っていることを知っていますが、あなたはアイデアを得るでしょう。

62
Guido

pull request (Ansible 2.2+で利用可能)を提出しました。これは、Ansibleで jmespath クエリサポートを追加することで、この種の状況を容易にします。あなたの場合、それは次のように機能します:

- debug: msg="{{ addresses | json_query(\"private_man[?type=='fixed'].addr\") }}"

戻ります:

ok: [localhost] => {
    "msg": [
        "172.16.1.100"
    ]
}
28
Filipe

辞書のリストをフィルタリングするには、 selectattr filterequalto test を使用できます。

network.addresses.private_man | selectattr("type", "equalto", "fixed")

上記にはJinja2 v2.8以降が必要です(Ansibleバージョンに関係なく)。


また、Ansible テストmatchおよびsearchがあります は、正規表現を使用します。

matchは文字列内で完全に一致する必要がありますが、searchは文字列内で一致する必要があります。

network.addresses.private_man | selectattr("type", "match", "^fixed$")

辞書のリストを文字列のリストに減らして、addrフィールドのリストのみを取得するには、 map filter を使用できます。

... | map(attribute='addr') | list

または、コンマ区切りの文字列が必要な場合:

... | map(attribute='addr') | join(',')

組み合わせると、このようになります。

- debug: msg={{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute='addr') | join(',') }}
94
udondan

必ずしも良いとは限りませんが、オプションがあるのはいいので、ここで Jinjaステートメント を使用して行う方法を示します。

- debug:
    msg: "{% for address in network.addresses.private_man %}\
        {% if address.type == 'fixed' %}\
          {{ address.addr }}\
        {% endif %}\
      {% endfor %}"

または、すべてを1行に入れたい場合:

- debug:
    msg: "{% for address in network.addresses.private_man if address.type == 'fixed' %}{{ address.addr }}{% endfor %}"

返されるもの:

ok: [localhost] => {
    "msg": "172.16.1.100"
}
14
bmaupin