используя regex в Джимму 2 для анзибль сценарии

Привет я новичок в jinja2 и пытаюсь использовать регулярное выражение, как показано ниже

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

на основе значения "сервер", я хотел бы оценить, как какие сертификаты использовать. т. е. если домен содержит ключевое слово "мышление", используйте эти сертификаты, и если он содержит ключевое слово" sleeping", используйте этот сертификат.

но не нашел фильтра jinja2, поддерживающего это. Пожалуйста, помогите мне.Я нашел код python и уверен, что он может работать, но как использовать python в jinja2 шаблоны?

7 ответов


Jinja2 может довольно легко выполнять проверки substr с помощью простого сравнения "in", например

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

поэтому фильтр регулярных выражений подстроки не требуется. Однако, если вы хотите более продвинутого сопоставления регулярных выражений, то там are на самом деле фильтров, доступных в анзибль - см. фильтры regex в http://docs.ansible.com/playbooks_filters.html#other-useful-filters - Как ни странно, ваш синтаксис совпадают почти точно.

+1 для Bereal это хотя, это дает хорошую альтернативу в виде карты.


существует фильтр "regex_replace", доступный в Ansible>1.6

Другие Полезные Фильтры Прокрутите вниз и вы увидите это:

новое в версии 1.6.

чтобы заменить текст в строке регулярным выражением, используйте фильтр "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<host>.+):(?P<port>\d+)$', '\g<host>, \g<port>') }}

при этом регулярное выражение является излишним для поиска решения этой конкретной проблемы.


благодаря Steve E. подсказка, я выяснил способ добавить регулярное выражение в условие шаблона:

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

Итак, после долгого поиска в гугле и с помощью некоторых блоггеров вот окончательное решение моей проблемы: -

1. Jinja2 не имеет фильтра для поиска подстроки или регулярного выражения, поэтому единственным решением было создать пользовательский фильтр. Я выполнил следующие шаги, чтобы исправить свою проблему.

2. внутри корневого каталога моего playbook я создал каталог "filter_plugins" и написал модуль в python и разместил файл внутри этого каталога. Имя файла python может быть любым. Мой код python выглядит следующим образом:

 __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. как только этот файл будет создан наш новый фильтр "substr" готов к использованию и может использоваться внутри шаблонов, как показано ниже:

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

в Ansible 2.1 есть некоторые (в настоящее время) недокументированные фильтры, которые могут делать то, что вам нужно:
Ansible plugins/filter.core.py

на regex_search filter выполнит регулярное выражение в строке и вернет полученное совпадение. Что-то похожее на это будет работать и будет содержаться в Анзибль роль:

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

также regex_findall фильтр, который выполняет поиск Python findall вместо регулярное выражение.

просмотрите оригинальный запрос pull для получения дополнительной информации


насколько мне известно, нет встроенного фильтра для этого в Jinja2 ни среди Ansible дополнительные фильтры, но это не большое дело, чтобы сделать свой собственный:

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

тогда вам нужно добавить плагин фильтра для Ansible, так что он будет использовать функцию выше в шаблонах (например,{{server|ssl_cert}} Если вы назовете фильтр ssl_cert).

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


Это довольно коряво, но он работает с 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 %}