Клавиша выхода из выпадающего списка Jinja2 в selectattr - PullRequest
1 голос
/ 11 июля 2019

В настоящее время я пытаюсь перебрать подмножество k8s_facts.Мой факт выглядит примерно так:

{
  "resources": [
  { 
    "metadata": {
      "annotations": {
         "com.foo.bar/name": "foo",
         "com.foo.bar/foo-name": "baz"
       },
       "creationTimestamp": "2018-12-20T02:29:50Z",
       "name": "foo-bar"
    }
  },
  ...

Я хочу отфильтровать по определенному значению клавиши com.foo.bar/foo-name.Поскольку клавиша имеет значения ., - и /, она не очень хорошо работает с функцией Jinja2 selectattr.Я пытался сделать что-то подобное, но напрасно:

- debug:
    msg: "{{ item }}"
    loop: "{{ my_fact.resources | selectattr('metadata.annotations[\\'com.foo.bar/foo-name\\']', 'defined') | selectattr('metadata.annotations[\\'com.foo.bar/foo-name\\']', 'match', 'baz') | list }}"
  loop_control: 
    label: "{{ item.metadata.name }}"

При выполнении предыдущего я получаю эту ошибку:

fatal: [<redacted>]: FAILED! => {"msg": "template error while templating string: expected token ',', got 'com'. String: {{ my_fact.resources | selectattr('metadata.annotations[\\\\'com.foo.bar/foo-name\\\\']', 'defined') | selectattr('metadata.annotations[\\\\'com.foo.bar/foo-name\\\\']', 'match', 'baz') | list }}"}

У меня вопрос, как я могу избежать сложных строкТочки в Jinja2?

Ответы [ 2 ]

3 голосов
/ 11 июля 2019

Когда я вхожу в выход из ада в ansible, я обычно использую синтаксис yaml свернутый и буквальный блок .Преимущество состоит в том, что он позволяет вам писать блоки jinja без необходимости заключать их в кавычки, что исключает один уровень цитирования и, следовательно, один экранирующий уровень.

В вашем случае, я думаю, вы можете перейти прямо к сути, используяjson_query фильтр вместо того, чтобы публиковать длинный список фильтров.

Вот демонстрационная пьеса:

---
- name: Test var names with dots
  hosts: localhost
  gather_facts: false

  vars:
    my_fact: {
      "resources": [
        {
          "metadata": {
            "annotations": {
              "com.foo.bar/name": "foo",
              "com.foo.bar/foo-name": "baz"
            },
            "creationTimestamp": "2018-12-20T02:29:50Z",
            "name": "foo-bar"
          }
        },
        {
          "metadata": {
            "annotations": {
              "com.foo.bar/name": "toto",
              "com.foo.bar/foo-name": "titi"
            },
            "creationTimestamp": "2018-12-21T02:30:50Z",
            "name": "foo-bla"
          }
        },
        {
          "metadata": {
            "annotations": {
              "com.foo.bar/name": "johnsmith",
              "com.foo.bar/foo-name": "baz"
            },
            "creationTimestamp": "2018-12-22T02:31:50Z",
            "name": "foo-john"
          }
        }
      ]
    }

  tasks:
    - name: Show results where metadata.annotations."com.foo.bar/foo-name"=='baz'
      vars:
        query: >-
          [?(metadata.annotations."com.foo.bar/foo-name")=='baz']
      debug:
        msg: "{{ item }}"
      loop: "{{ my_fact.resources | json_query(query) }}"
      loop_control:
        label: "{{ item.metadata.name }}"

И результат

PLAY [Test var names with dots] *******************************************************************************************************************************************************************************************

TASK [Show results where metadata.annotations."com.foo.bar/foo-name"=='baz'] **********************************************************************************************************************************************
ok: [localhost] => (item=foo-bar) => {
    "msg": {
        "metadata": {
            "annotations": {
                "com.foo.bar/foo-name": "baz",
                "com.foo.bar/name": "foo"
            },
            "creationTimestamp": "2018-12-20T02:29:50Z",
            "name": "foo-bar"
        }
    }
}
ok: [localhost] => (item=foo-john) => {
    "msg": {
        "metadata": {
            "annotations": {
                "com.foo.bar/foo-name": "baz",
                "com.foo.bar/name": "johnsmith"
            },
            "creationTimestamp": "2018-12-22T02:31:50Z",
            "name": "foo-john"
        }
    }
}

PLAY RECAP ****************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

0 голосов
/ 11 июля 2019

Q: "I want to filter on a specific value of the com.foo.bar/foo-name key"

A: Задание ниже выполняет работу

- debug:
    msg: "{{ resources|json_query(my_query) }}"
  vars:
    my_query: '[?metadata.annotations."com.foo.bar/foo-name"==`baz`]'
...