#python #ansible #jinja2
Вопрос:
У меня есть следующее в шаблоне ansible.
{% if value.http_requests is defined %}
{% for http_request in value.http_requests %}
http-request {{ http_request }}
{% endfor %}
{% endif %}
http_requests обычно определяется в сборнике игр следующим образом:
http_requests:
- randomhttprequest
Если переменная определена, но список пуст, то шаблон покажет http-запрос без значения.
Я изо всех сил пытаюсь найти способ провалить учебник, даже если список http_requests остается пустым, как это
http_requests:
-
-
Я пробовал использовать длину, а не ничего, но, похоже, я не могу заставить это работать.
Комментарии:
1. Я не думаю, что это пустая переменная, а скорее список с двумя пустыми строками.
2. извините, что вы правы, я новичок в изучении этих вещей. вопрос все еще остается с пустым списком
3. вы хотите специально провалить учебник в том случае, если список пуст?
4. @RafadeBoas да
5. @user3925030 в вашем примере с «пустым» списком список на самом деле не пустой. он состоит из двух пустых списков… другими словами:
http_requests = [[], []]
.
Ответ №1:
Вопрос: «Намеренно провалите учебник в случае, если список был пуст».
Ответ: Есть много вариантов того, как протестировать его и изящно провалиться. Например, вы можете использовать assert
- assert:
that: value.http_requests|default([])|length == 0
fail_msg: Error. Tne list value.http_requests is empty.
Чтобы проверить, являются ли все дочерние элементы списка «пустыми» (как в [[], [], …]) вы можете использовать расширяемые функции map, length и sum. Например
- hosts: localhost
vars:
http_requests1:
- randomhttprequest
- ""
http_requests2:
- ""
- ""
tasks:
- name: Sanity http_requests1
assert:
that: http_requests1|map('length')|sum > 0
fail_msg: Error. All items of the list http_requests are empty.
- name: Sanity http_requests2
assert:
that: http_requests2|map('length')|sum > 0
fail_msg: Error. All items of the list http_requests are empty.
дает
ok: [localhost] => changed=false
msg: All assertions passed
fatal: [localhost]: FAILED! => changed=false
assertion: http_requests2|map('length')|sum > 0
evaluated_to: false
msg: Error. All items of the list http_requests are empty.
Чтобы избежать undefined variable
ошибок в шаблоне, используйте фильтр по умолчанию, например
{% for http_request in value.http_requests|default([]) %}
http-request {{ http_request }}
{% endfor %}
Проверьте также длину цикла, если вы хотите повторить только непустую строку, например
- name: Iterate only non-empty strings
debug:
msg: |
{% for http_request in http_requests1|default([]) %}
{% if http_request|length > 0 %}
http-request {{ http_request }}
{% endif %}
{% endfor %}
дает
msg: |-
http-request randomhttprequest
Комментарии:
1. я спросил спрашивающего, хотели ли они намеренно провалить учебник в случае, если список был пуст, чтобы это не решило их проблему
2. Спасибо. Это прояснило дело. Я обновил ответ.
3. я считаю, что спрашивающий ищет способ проверить, является ли список списков пустым (из-за их примера «пустой список»). использование длины здесь было бы недостаточно (см. Мой ответ ниже)
4. Конечно. Я уже сделал это. И обновил ответ и по этому делу. Спасибо.
5. Очень красиво и очень элегантно!
Ответ №2:
Чтобы проверить, все ли дочерние элементы списка «пусты» (как в [[], [], ...]
), вы можете использовать некоторые встроенные модули Python:
# This will return True
example_list = [[], []]
empty = all(not l for l in map(lambda l: bool(l), example_list))
# This will return False
example_list = [[1, 2], []]
empty = all(not l for l in map(lambda l: bool(l), example_list))
Я создал образец сборника пьес, который делает именно это:
- name: Check for empty list example
hosts: localhost
connection: local
vars:
example_list:
-
-
tasks:
# Calling Python here is necessary because Jinja2 doesn't have
# an `all()` filter, so I had to improvise.
- name: check for empty list
register: result
args:
stdin: |
print(all(not l for l in map(lambda l: bool(l), {{ example_list }})))
command: python
- debug:
msg: 'list is empty'
# String comparison because we're `print()`ing the result
# of the Python expression...
when: result.stdout == "True"
- name: lets fail
debug:
msg: 'list is not empty'
failed_when: result.stdout == "True"
Это, без сомнения, очень некрасиво. Тем не менее, он выполняет свою работу.