HI 私は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 %}
の値に基づいて、どの証明書を使用するかを評価したいと思います。 例えば、もしドメインが "thinking" キーワードを含んでいれば、これらの証明書を使用し、もし "sleeping" キーワードを含んでいれば、その証明書を使用します。
しかし、これをサポートするjinja2フィルターが見つかりませんでした。 Pythonのコードをいくつか見つけ、確かにそれは動作しますが、jinja2テンプレートでPythonを使用するにはどうすればよいですか?
Jinja2 は単純な 'in' 比較で非常に簡単に substr チェックができます。
{% set server = 'www.thinkingmonster.com' %}
{% if 'thinking' in server %}
do something...
{% endif %}
そのため、部分文字列の正規表現フィルタは必要ありません。 しかし、より高度な正規表現マッチングをしたいのであれば、ansibleで利用できるフィルタがあります。http://docs.ansible.com/playbooks_filters.html#other-useful-filters の regex filters を見てください。面白いことに、上記のマッチ構文はほぼ正確です。
Bereal's answer](https://stackoverflow.com/a/30413899/2947502)には+1, マップという形で素晴らしい代替手段を提供してくれています。
そこで、長い間ググって、何人かのブロガーの助けを借りて、私の問題に対する最終的な解決策をご紹介します:-)
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 %}
私の知る限りでは、Jinja2にもAnsibleのextra filtersにもそのための組み込みフィルタはありませんが、自分で作るのはたいしたことではありません。
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 に filter plugin を追加して、テンプレートで上記の関数を使用するようにします (フィルター名を ssl_cert
とすると `{server|ssl_cert}} のようになります)。
とはいえ、テンプレートに渡され、そこで明示的に使用される古い関数や古い辞書は、この仕事にもっとフィットするかもしれません。