Как наследовать неопределенные переменные с помощью Jinja2?

0

Вопрос

В моих ролях Ansible некоторые роли получают определенные параметры конфигурации из глобальных переменных Глобальные переменные могут быть неопределенными. Следующий код иллюстрирует схему:

- hosts: localhost
  vars:
    bar: '{{ foo }}'
  tasks:
    # Assume foo comes from an Ansible environment
    - debug: var=foo
    # Assume bar comes from a role default
    - debug: var=bar
    # Catched by the "is defined" condition
    - debug: msg="foo is defined"
      when: 'foo is defined'
    # Cannot catch undefined exception?!
    - debug: msg="bar is defined"
      when: 'bar is defined'

Все работает так, как ожидалось, но последнее утверждение: Ansible вызывает исключение, потому что foo не определено (да, оно не определено).

PLAY [localhost] *********************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************
ok: [localhost]

TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
    "foo": "VARIABLE IS NOT DEFINED!"
}

TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
    "bar": "VARIABLE IS NOT DEFINED!"
}

TASK [debug] *************************************************************************************************************************************************************
skipping: [localhost]

TASK [debug] *************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'bar is defined' failed. The error was: error while evaluating conditional (bar is defined): {{ foo }}: 'foo' is undefined\n\nThe error appears to be in '.../test-undef.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n      when: 'foo is defined'\n    - debug: msg=\"bar is defined\"\n      ^ here\n"}

Так почему же bar не “оценивать”, чтобы undefined Нравится foo? И как я могу уловить эту “многоуровневую” неопределенность?

ansible jinja2
2021-11-23 09:46:53
3
0

Попробуйте это:

- hosts: localhost
  vars:
    bar: '{{ foo }}'
  tasks:
    # Assume foo comes from an Ansible environment
    - debug: var=vars.foo
    # Assume bar comes from a role default
    - debug: var=vars.bar
    # Catched by the "is defined" condition
    - debug: msg="foo is defined"
      when: vars.foo is defined
    # Cannot catch undefined exception?!
    - debug: msg="bar is defined"
      when: vars.bar is defined
2021-11-23 09:57:21

@Frenchy: Да, действительно... И если вы запустите мой скрипт, то увидите, что он работает нормально...
Swifty

да...я согласен с вами,
Frenchy

Спасибо, @Swifty. Тем не менее, Ansible показывает vars.bar как определено в вашем коде: text TASK [debug] ************************************************************************************************************************************************************* ok: [localhost] => { "msg": "bar is defined" } Вероятно, потому, что в нем содержится строка шаблона?
Stephan

да, это правильно, так что foo определен, означает, что бар определен
Frenchy

Но foo не определено ...
Stephan

foo не определен подразумевает, что бар не определен..вам просто нужно проверить, определен ли foo, чтобы проверить, определен ли bar
Frenchy

@Стефан, пожалуйста, поймите разницу между '{{ foo }}' и "{{ foo }}"... "{{ foo }}" означает переменную... '{{ foo }}' буквально означает эту строку...
Swifty
0

Проблема в том, что бар технически определен, и ваше определение bar использует, возможно, неопределенную переменную. Когда вы пытаетесь что-либо сделать с bar это должно быть оценено как независимое выражение Дзиндзя, которое происходит до is defined проверять.

Один из способов решить эту проблему-сделать ее такой bar может быть оценена без получения неопределенного значения, например

- hosts: localhost
  vars:
    bar: "{{ foo | default(false) }}"
  tasks:
    - debug:
        msg: bar is truthy
      when: bar is truthy

Вы также можете проверить foo перед баром, так как оценка может быть короткой, но знание взаимосвязи переменных в ваших задачах может быть громоздким.

- hosts: localhost
  vars:
    bar: "{{ foo }}"
  tasks:
    - debug:
        msg: bar is truthy
      when: 
        - foo is defined
        - bar is defined
2021-11-23 17:15:56

Пожалуйста, обратите внимание, что @Stephan определил переменную bar как строку! bar: '{{ foo }}' буквально означает "жало"!!!
Swifty
-1

попробуйте добавить

when: ( vars[bar] is defined )
2021-11-23 15:28:45

vars-это недокументированная внутренняя реализация, которая может быть удалена в будущем и не должна использоваться.
flowerysong

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................