2016-06-10 15 views
6

Sto cercando di ciclo di un dizionario attraverso un modello ansible utilizzando Jinja2 per creare un certo numero di fonti di dati, ma questo errore [{'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'dict object' has no attribute 'value'", 'failed': True}]}dizionario Loop in modello ansible

Durante l'esecuzione di un compito di debug lo fa arrivare i valori corretti indietro in modo Mi sento come se il mio problema fosse nel modello stesso, ma non sono stato in grado di capire cosa sto facendo male.

Ansible Task

- 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 

Ansible dizionario

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 Template

{% 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 %} 

output di debug

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

Perché la seconda attività utilizza sia 'with_items' che' with_dict', soprattutto quando sembra che non stia facendo uso di quest'ultima? Sarei molto sorpreso se ciò funzionasse effettivamente. – jwodder

+0

Hmm originariamente avevo più file in questa attività usando with_items. L'ho rimosso ma continuo a riscontrare lo stesso problema. Ha comunque senso separarli, grazie. – tweeks200

risposta

3

È possibile raggiungere il tuo obiettivo modificando il modello Jinja2 e il compito in questo modo:

Jinja2 Template:

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

Compiti ansible:

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

Speranza che potrebbero aiutarvi, per favore regolate le vostre attività secondo il vostro requisito

+0

Funziona perfettamente, grazie! – tweeks200

6

In Jinja, quando databases è un dizionario, for items in databases sarà (come in Python) un'iterazione sulle chiavi del dizionario, non le sue coppie chiave/valore. Pertanto, nel modello, item.value (che presumo sia destinato a items.value) deve essere databases[items] per ottenere il valore associato alla chiave items.

+0

Sembra fare progressi. Ricevo "Una o più variabili non definite: l'oggetto dict non ha elementi" ora ma i valori si mostrano nell'output dell'errore. Tutte le variabili hanno valori nell'output. Qualche idea? – tweeks200

2

Ho scoperto oggi che l'uso di dict.values ​​() esegue il ciclo su tutti i valori di ciascun elemento di dict anziché sulle sue chiavi. Quindi dovresti essere in grado di usare qualcosa del genere per il tuo modello.

{% 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 %} 

so che la sua strada dopo il fatto, ma forse qualcun altro alla ricerca di questa risposta può fare uso di questa scoperta supplementare.

Problemi correlati