usando regex en jinja 2 para libros de juego ansible

Hola, soy nuevo en jinja2 y trato de usar expresiones regulares como se muestra a continuación

{% if ansible_hostname == 'uat' %} {% set server = 'thinkingmonster.com' %} {% else %} {% set server = 'define yourself' %} {% endif %} {% if {{ server }} match('*thinking*') %} {% set ssl_certificate = 'akash' %} {% elif {{ server }} match( '*sleeping*')%} {% set ssl_certificate = 'akashthakur' %} {% endif %} 

basado en el valor de “servidor” me gustaría evaluar qué certificados usar. es decir, si el dominio contiene la palabra clave “pensando”, use estos certificados y si contiene la palabra clave “inactivo”, use ese certificado.

Pero no encontré ningún filtro jinja2 que soporte esto. Por favor, ayúdeme. Encontré un código de Python y estoy seguro de que puede funcionar, pero ¿cómo usar Python en las plantillas jinja2?

Jinja2 puede realizar comprobaciones de substr con una simple comparación “in”, por ejemplo,

 {% set server = 'www.thinkingmonster.com' %} {% if 'thinking' in server %} do something... {% endif %} 

Por lo que no se requiere su filtro de expresiones regulares de subcadena. Sin embargo, si desea una comparación más avanzada de expresiones regulares, entonces de hecho hay filtros disponibles en ansible – vea los filtros de expresiones regulares en http://docs.ansible.com/playbooks_filters.html#other-useful-filters – curiosamente, su syntax de coincidencia Lo anterior es casi exactamente correcto.

Sin embargo, +1 para la respuesta de Bereal , da una buena alternativa en forma de mapa.

Hay un filtro “regex_replace” disponible en Ansible> 1.6

Otros filtros útiles Desplácese hacia abajo y verá esto:

Nuevo en la versión 1.6.

Para reemplazar el texto en una cadena con expresiones regulares, use el filtro “regex_replace”:

 # convert "ansible" to "able" {{ 'ansible' | regex_replace('^a.*i(.*)$', 'a\\1') }} # convert "foobar" to "bar" {{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }} # convert "localhost:80" to "localhost, 80" using named groups {{ 'localhost:80' | regex_replace('^(?P.+):(?P\\d+)$', '\\g, \\g') }} 

Dicho esto, la expresión regular es una exageración para encontrar una solución a este problema en particular.

Gracias a la sugerencia de Steve E., he descubierto una manera de agregar expresiones regulares en una condición de plantilla:

 {% if server | regex_search('thinking') %} .... {% endif %} 

Entonces, después de buscar en Google durante mucho tiempo y con la ayuda de algunos bloggers, aquí está la solución final a mi problema:

1. Jinja2 no tiene ningún filtro para buscar sub-cadenas o expresiones regulares, por lo que la única solución fue crear un filtro personalizado. Seguí los pasos a continuación para solucionar mi problema.

2. Dentro del directorio raíz de mi libro de jugadas, creé un directorio “filter_plugins”, escribí un módulo personalizado en Python y coloqué el archivo dentro de este directorio. El nombre del archivo python puede ser cualquier cosa. Mi código de python se ve como sigue:

  __author__ = 'akthakur' class FilterModule(object): ''' Custom filters are loaded by FilterModule objects ''' def filters(self): ''' Filter Module objects return a dict mapping filter names to filter functions. ''' return { 'substr': self.substr, } ''' def substr(self, check,checkin): return value1+value2''' def substr(self,check,checkin): if check in checkin: return True else: return False 

3. Una vez que se crea este archivo, nuestro nuevo filtro “substr” está listo para usar y se puede usar dentro de las plantillas como se muestra a continuación:

 {% if 5==5 %} {% set server = 'www.thinkingmonster.com' %} {% endif %} {% if 'thinking' | substr(server) %} {% set ssl_cert = 'abc.crt'%} {% endif %} 

Hay algunos filtros (actualmente) sin documentar en Ansible 2.1 que pueden hacer lo que necesitas:
Ansible plugins / filter.core.py

El filtro regex_search realizará una expresión regular en la cadena y devolverá la coincidencia resultante. Algo similar a esto funcionaría y estaría contenido dentro de un rol de Ansible:

 {% set server = 'www.thinkingmonster.com' %} {% if regexp_search(server, 'thinking') %} do something... {% endif %} 

También hay un filtro regex_findall que realiza una búsqueda en Python findall en lugar de regex.

Revise la solicitud de extracción original para obtener más información.

Esto es bastante feo, pero funciona a partir de 1.6.

 {% if server|regex_replace('.*thinking.*','matched') == 'matched' %} {% set ssl_certificate = 'akash' %} {% elif server|regex_replace('.*sleeping.*','matched') == 'matched' %} {% set ssl_certificate = 'akashthakur' %} {% endif %} 

Que yo sepa, no hay un filtro integrado para eso en Jinja2 ni entre los filtros adicionales de Ansible, pero no es gran cosa hacer el suyo:

 certs = {'.*thinking.*': 'akash', '.*sleeping.*': 'akashthakur'} def map_regex(value, mapping=certs): for k, v in mapping.items(): if re.match(k, value): return v 

Luego deberá agregar un complemento de filtro a Ansible, de modo que use la función anterior en las plantillas (como {{server|ssl_cert}} si nombra el filtro ssl_cert ).

Dicho esto, una función simple anterior o un diccionario antiguo simple que se pasa a las plantillas y se usa allí explícitamente podría ajustarse mejor a este trabajo.