繁体   English   中英

如何在 Python 中使用 pip 安装的 jinja2 过滤器

[英]How to use pip-installed jinja2 filters in Python

在我的 Ansible 项目中,我使用pip安装了库,允许我使用额外的 jinja2 过滤器。

其中,我安装了允许我使用ipaddr过滤器的netaddr库,如下所示: <netmask>{{ interface.IP | ipaddr('netmask') }}</netmask> <netmask>{{ interface.IP | ipaddr('netmask') }}</netmask> (这适用于我的 Ansible 剧本)

当我尝试通过创建一个快速的 Python 脚本来测试我的模板而不必运行我的 Ansible playbook 时,问题就出现了。 例如:

from jinja2 import Template
print Template('{{ ip | ipaddr("netmask") }}').render(ip='10.10.10.0/24')

抛出以下异常:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 945, in __new__
  return env.from_string(source, template_class=cls)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 880, in from_string
  return cls.from_code(self, self.compile(source), globals, None)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 591, in compile
  self.handle_exception(exc_info, source_hint=source_hint)
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "<unknown>", line 1, in template
jinja2.exceptions.TemplateAssertionError: no filter named 'ipaddr'

我可以在最后一行中看到 jinja2 找不到安装在/usr/lib/python2.7/dist-packages的“ipaddr”过滤器,但我找不到如何直接使用通过 pip 安装的包在我的 Python 脚本中。

是的,你可以这样做。 Ansible 需要在你的 python 路径中

import jinja2
from ansible.plugins.filter import ipaddr

template_dir = 'path/to/templates'
fname = 'template.txt'

# get the filters from ansible/plugins/filter/ipaddr
f = ipaddr.FilterModule()

# for a template in your filesystem, set the loader
loader = jinja2.FileSystemLoader(template_dir)

# create the environment
env = jinja2.Environment(loader=loader)

# *** Add the ipaddr filters to the environment ***
env.filters.update(f.filters())

# Set your template
template = env.get_template(fname)

print(template.render(ip='10.10.10.0/24'))

这将使您的模板文件(包含{{ ip | ipaddr("netmask") }} )输出

255.255.255.0

我花了一个小时的大部分时间试图让它工作,这完全是一场噩梦。 我最终不得不放弃。 虽然它可能仍然是可能的,但我无法在任何地方获得太多,甚至创建Environment()并尝试加载扩展等等。

我最终做的是使用这里提到的解决方案之一: How can I test jinja2 templates in ansible?

(该解决方案还提到了一些在线 Jinja2 解析器,但这些解析器似乎遇到了与交互式 Python 方法完全相同的问题。)

我最终采用的是Ansible_3Ansible_4解决方案的组合 -

我创建了一个名为nametest.yml如下所示:

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template: src=name.j2 dest=output.conf

然后我将我的测试 Jinja2 内容放在name.j2文件中。

我进行了这样的测试:

ansible-playbook nametest.yml --check --diff --connection=local -e role=api -e level=prod -e '{"item": {"private_ip": "1.2.3.4"}}' -e debug_instance=false

这些-e选项分别设置一个变量的值。 大多数情况下,我只是使用了简单的name=value构造,但对于更复杂的嵌套对象,我使用了 JSON 版本。

然后为了使用不同的变量值运行,我只是摆弄各种命令行参数来测试我设置的所有代码分支。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM