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

时间:2018-04-18 15:31:20

标签: python jinja2

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

其中,我安装了netaddr库,允许我使用ipaddr过滤器,如下所示:<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无法找到&#39; ipaddr&#39;过滤器,这是 已安装在/usr/lib/python2.7/dist-packages中,但我无法在Python脚本中找到如何直接使用pip安装的软件包。

2 个答案:

答案 0 :(得分:2)

是的,您可以这样做。 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

答案 1 :(得分:0)

我花了一个小时的大部分时间试图使它正常工作,这完全是一场噩梦。我最终不得不放弃。尽管这仍然可能,但我什至无法实现任何目标,甚至无法创建Environment(),并尝试加载扩展名和其他内容。

我最终要做的是使用此处提到的一种解决方案:How can I test jinja2 templates in ansible?

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

我最终选择的是 Ansible_3 Ansible_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版本。

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