2016-06-10 2 views
6

Я пытаюсь Переберите словарь через анзибль шаблон с помощью jinja2 создать несколько источников данных, но эту ошибку [{'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'dict object' has no attribute 'value'", 'failed': True}]}словарь Петли в анзибле шаблона

При выполнении задачи отладки он делает получить правильные значения обратно так Я чувствую, что моя проблема в самом шаблоне, но я не мог понять, что я делаю неправильно.

анзибль Задача

- name: debug dictionary 
    debug: msg="{{ item.value.db_url }}" 
    with_dict: databases 

- name: copy tomcat config files 
    template: src="{{ item.src }}" dest="{{ item.dest }}" 
    with_items: 
    - { src: 'context.xml.j2', dest: '/opt/tomcat/conf/context.xml'} 
    notify: restart tomcat 
    with_dict: databases 

анзибль словарь

databases: 
    db1: 
    db_resource: jdbc/db1 
    db_maxidle: 50 
    db_maxconn: 350 
    db_maxwait: 10000 
    db_user: dbuser 
    db_pass: "{{ dbpass }}" 
    db_url: jdbc:postgresql://server:5432/dbname 
    db_driver: org.postgresql.Driver 

Jinja2 Шаблон

{% for items in databases %} 
    <resource name="{{ item.value.db_resource }}" auth="container" type="javax.sql.datasource" maxtotal="{{ item.value.db_maxconn }}" maxidle="{{ item.value.db_maxidle }}" maxwaitmillis="{{ item.value.db_maxwait }}" username="{{ item.value.db_user }}" password="{{ item.value.db_pass }}" driverclassname="{{ item.value.db_driver }}" url="{{ item.value.db_url }}" /> 
{% endfor %} 

Debug Output

ok: [IP] => (item={'key': 'db1', 'value': {'db_maxwait': 10000, 'db_maxconn': 350, 'db_maxidle': 50, 'db_driver': 'org.postgresql.Driver', 'db_pass': u'REDACTED', 'db_resource': 'jdbc/db1', 'db_user': 'dbuser', 'db_url': 'jdbc:postgresql://server:5432/dbname'}}) => { 
    "item": { 
     "key": "db1", 
     "value": { 
      "db_driver": "org.postgresql.Driver", 
      "db_maxconn": 350, 
      "db_maxidle": 50, 
      "db_maxwait": 10000, 
      "db_pass": "REDACTED", 
      "db_resource": "jdbc/db1", 
      "db_url": "jdbc:postgresql://server:5432/db", 
      "db_user": "dbuser" 
     } 
    }, 
    "msg": "jdbc:postgresql://server:5432/dbname" 
} 
+0

Почему ваша вторая задача используется как 'with_items', так и' with_dict', особенно если она, похоже, не использует последний? Я был бы очень удивлен, если бы это действительно сработало. – jwodder

+0

Хмм первоначально у меня было несколько файлов в этой задаче, используя with_items. Я удалил его, но все равно столкнулся с той же проблемой. Имеет смысл разделить их, хотя, спасибо. – tweeks200

ответ

3

Вы можете достичь своей цели путем изменения шаблона jinja2 и задачи, как это:

Jinja2 шаблона:

<resource name="{{ databases[item].db_resource }}" auth="container" type="javax.sql.datasource" maxtotal="{{ databases[item].db_maxconn }}" maxidle="{{ databases[item].db_maxidle }}" maxwaitmillis="{{ databases[item].db_maxwait }}" username="{{ databases[item].db_user }}" password="{{ databases[item].db_pass }}" driverclassname="{{ databases[item].db_driver }}" url="{{ databases[item].db_url }}" /> 

анзибль Задачи:

- name: debug dictionary 
    debug: msg="{{ databases[item].db_url }}" 
    with_items: "{{ databases | list }}" 

- name: copy tomcat config files 
    template: src="{{ item.src }}" dest="{{ item.dest }}" 
    with_items: 
    - { src: 'context.xml.j2', dest: '/opt/tomcat/conf/context.xml'} 
    notify: restart tomcat 
    with_items: "{{ databases | list }}" 

Надежда, что может помогите вам, пожалуйста, скорректируйте свои задачи согласно вашему требованию

+0

Это работает отлично, спасибо! – tweeks200

6

В Джиндже, когда databases является словарь, for items in databases будет (как в Python) перебрать ключи словаря, а не его пары ключ/значение. Таким образом, в вашем шаблоне item.value (который я предполагаю, должен быть items.value) должен быть databases[items], чтобы получить значение, связанное с ключом items.

+0

Это похоже на прогресс. Я получаю «Один или несколько неопределенных переменных: у объекта dict нет элемента», но значения отображаются в выводе ошибки. Все переменные имеют значения на выходе. Есть идеи? – tweeks200

2

Я обнаружил сегодня, что использование dict.values ​​() пересекает все значения элемента dict, а не его ключи. Таким образом, вы можете использовать что-то подобное для своего шаблона.

{% for item in databases.values() %} 
    <resource name="{{ item.db_resource }}" auth="container" type="javax.sql.datasource" maxtotal="{{ item.db_maxconn }}" maxidle="{{ item.db_maxidle }}" maxwaitmillis="{{ item.db_maxwait }}" username="{{ item.db_user }}" password="{{ item.db_pass }}" driverclassname="{{ item.db_driver }}" url="{{ item.db_url }}" /> 
{% endfor %} 

Я знаю, что это путь постфактум, но, возможно, кто-то искал этот ответ может использовать это дополнительное открытие.

Смежные вопросы