Ansible : 속성별로 목록 필터링


84

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" }}

구문이 잘못되었다는 것을 알고 있지만 아이디어를 얻었습니다.

답변:


41

Ansible에 jmespath 쿼리 지원을 추가하여 이러한 종류의 상황을 더 쉽게 만들 수 있는 pull 요청 (Ansible 2.2 이상에서 사용 가능)을 제출했습니다 . 귀하의 경우에는 다음과 같이 작동합니다.

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

반환됩니다 :

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

3
json_query 필터를 실행하기 전에 "jmespath"를 설치해야합니다.
.01.24

그리고 파이썬 버전 차이로 인해 jmespath 설치를 포기했습니다. 이 2.4+ Ansible에 보이는대로 그것은 사소한 솔루션으로이 아니다
스튜어트 와트

1
@StuartWatt 운영 체제 파이썬 버전에서 벗어나기 위해 pyenv가 필요할 수 있습니다. pyenv, pyenv virtualenvs를 시도하거나 어떤 사람들은 pipenv를 선호 할 수 있습니다. 그들은 모두 동일하게 작동합니다.
Jepper

@Jepper Ansible을 사용하기 위해 완전히 새로운 Python이 필요하다면 패배입니다. (그리고 나는이 문제 :-)했다 여전히 pyenv를 사용하여 한
스튜어트 와트를

128

딕셔너리 목록을 필터링하려면 equalto 테스트 와 함께 selectattr 필터를 사용할 수 있습니다 .

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

위의 버전에는 Jinja2 v2.8 이상이 필요합니다 (Ansible 버전에 관계없이).


Ansible 에는matchsearch 정규식을 사용 하는 테스트 있습니다 .

match문자열에서 완전히 일치 search해야하는 반면 문자열 내부에서 일치해야합니다.

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

딕셔너리 목록을 문자열 목록으로 줄여서 addr필드 목록 만 가져 오려면 map 필터를 사용할 수 있습니다 .

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

또는 쉼표로 구분 된 문자열을 원하는 경우 :

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

결합하면 다음과 같이 보일 것입니다.

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

1
쉼표로 구분 된 문자열이 아닌 목록으로 원하는 경우 다음을 사용할 수도 있습니다.{{ network.addresses.private_man | selectattr("type", "equalto", "fixed") | map(attribute='addr') | list }}
TrinitronX

1
제공 한 링크가 변경 되었습니까? 해당 페이지에서 "일치"및 "검색"을 찾을 수 없습니다
activedecay

1
@activedecay 그 페이지에서 사라진 것 같습니다. 지금 찾을 수있는 유일한 언급은이 페이지입니다. docs.ansible.com/ansible/latest/user_guide/… 링크를 업데이트했습니다. 감사합니다!
udondan

19

반드시 더 나은 것은 아니지만 여기에 옵션이있는 것이 좋기 때문에 다음을 사용하여 수행하는 방법이 있습니다. Jinja 문을 같습니다.

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

또는 모두 한 줄에 입력하려면 다음을 수행하십시오.

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

다음을 반환합니다.

ok: [localhost] => {
    "msg": "172.16.1.100"
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.