Utilice la variable para el valor predeterminado si falla la función importada

Oct 06 2020

Tengo un rol ansible que lee datos de una base de datos. Es posible que esos datos no existan, en cuyo caso fallarán. No puedo cambiar este rol. Actualmente estoy usando este rol como:

- name: Import role and read values
  import_role:
      name: shared_role
  register: value

Esto funciona bien cuando los datos en la base de datos existen y el rol no falla. Sin embargo, cuando faltan esos datos, están causando más problemas. Entonces, en caso de un error, quiero ignorar ese error y usar un valor predeterminado.

- import_role:
      name: shared_role
  register: value
  ignore_errors: true
- set_fact:
    value: "{{ value | default({{ default_var }}) }}"

donde default_var se define en group_vars. Ahora bien, esto no funciona obviamente y estoy un poco atascado. ¿Cómo podría usar una variable como valor predeterminado para otra variable registrada en un rol que podría haber fallado ... si eso tiene sentido?

Respuestas

3 Zeitounator Oct 06 2020 at 13:35

defaultpor defecto (perdón por esta redundancia, pero no sé cómo escribirlo mejor) reemplazará los valores solo para las variables indefinidas . Una variable definida como None se define.

Afortunadamente, hay un segundo parámetro que puede usarse para reemplazar también vars "vacías" (es decir None, o cadena vacía). Consulte la documentación para esto

Además, no puedes usar la expansión jinja2 mientras estás dentro de una expansión jinja2. Consulte la documentación de jinja2 para obtener más información.

Por lo tanto, debe cumplir con su requisito con la siguiente expresión (si todo lo que describió sobre sus datos es correcto):

- set_fact:
    value: "{{ value | default(default_var, true) }}"

No debería tener problemas con la precedencia variable aquí: set_facty registerestá en el mismo nivel, por lo que debería ganar la última asignación. Pero para mayor claridad y seguridad, cambiaría el nombre de esa var para que esté seguro de que nunca se mete en problemas:

- import_role:
    name: shared_role
  register: role_value
  ignore_errors: true
- set_fact:
    value: "{{ role_value | default(default_var, true) }}"
1 JBone Oct 06 2020 at 13:30

Aquí está mi group_vars/all.ymlarchivo. Estoy usando lo foodque se define aquí para establecer en mi juego. puede ver el valor 6en la salida.

 logs: /var/log/messages
   foo: 6

y aquí está mi libro de jugadas

   ---
   - name: assign a variable value in default state
     hosts: localhost
     tasks:
     - name: set fact and then print
       set_fact:
         new_var: "{{ doodle | default( foo ) }}"
     - name: debug
       debug: msg="{{ new_var }}"

y aquí está la salida

PLAY [assign a variable value in default state] ********************************

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

TASK [set fact and then print] *************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
   

>  "msg": "6"

}

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




  
1 toydarian Oct 06 2020 at 13:30

Este es un simple error de sintaxis. No se puede utilizar {{}}en un filtro.
La sintaxis correcta es

- set_fact:
    value: "{{ value | default(default_var) }}"

EDITAR:
Si su valor es "None"y desea reemplazarlo, puede usar algo como esto:

- set_fact:
    value: "{%- if not value is defined or value == 'None' -%}{{ default_var }}{%- else -%}{{ value }}{%- endif -%}"

Tome nota del uso de {{}}aquí.