Recursion Jinja2-在递归循环中连接字符串

Recursion Jinja2-在递归循环中连接字符串,recursion,jinja2,string-concatenation,Recursion,Jinja2,String Concatenation,我有一个yaml ansible文件,如: _app_config: APP: server: '"https://tst.example.com"' uploadRefreshRate: 10 autonomous: active: "false" SiteId: 47 tests: test1: 1 APP.server = "https://tst.example.com" APP.uploadRefr

我有一个yaml ansible文件,如:

_app_config:   
  APP:
    server: '"https://tst.example.com"'
    uploadRefreshRate: 10
    autonomous:
      active: "false"
      SiteId: 47
      tests:
        test1: 1
APP.server = "https://tst.example.com"
APP.uploadRefreshRate = 10
    APP.autonomous.active = false
    APP.autonomous.SiteId = 47
      APP.autonomous.tests.test1 = 1
我想解析它并创建一个配置文件,如:

_app_config:   
  APP:
    server: '"https://tst.example.com"'
    uploadRefreshRate: 10
    autonomous:
      active: "false"
      SiteId: 47
      tests:
        test1: 1
APP.server = "https://tst.example.com"
APP.uploadRefreshRate = 10
    APP.autonomous.active = false
    APP.autonomous.SiteId = 47
      APP.autonomous.tests.test1 = 1
因此,我的jinja2模板如下所示:

{%  if _app_config is defined %}
{%    if _app_config.APP is defined %}
{%      set key_chain = '' %}
{%      for key,value in _app_config.APP.iteritems() recursive %}
{%        if value is mapping %}
{%          set key_chain = key_chain + key %}
            {{ loop(value.iteritems()) }}
{%        else %}
{%          set param = 'APP.' + key_chain | string + '=' + value | string %}
{{ param | indent(loop.depth) }}
{%        endif %}
{%      endfor %}
{%    endif %}
{%  endif %}
因此,结果不是预期的结果:)

值未排序,并且键链连接不起作用


谢谢你的帮助

下面的python“filter_plugin”实现了以下功能:

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type


ANSIBLE_METADATA = {
    'metadata_version': '1.1',
    'status': ['preview'],
    'supported_by': 'community'
}


from ansible.errors import AnsibleFilterError

def dict_path(my_dict, path=None, sort=True):
    if isinstance(my_dict, dict):
        def recurse(values, path):
            for k, v in values.iteritems():
                newpath = path + [k]
                if isinstance(v, dict):
                    for u in recurse(v, newpath):
                        yield u
                else:
                    yield newpath, v
        if path is None:
            path = []
        g=recurse(my_dict, path)
        if sort:
            return sorted(sorted(g, key=lambda item: len(item[0])), key=lambda item: '.'.join(item[0]))
        else:
            return g
    else:
        raise AnsibleFilterError(my_dict + 'must be a dictionary')

# ---- Ansible filters ----
class FilterModule(object):
    ''' Dict path filter '''
    def filters(self):
        return {
            'dict_path': dict_path
        }
并将此代码添加到模板中:

{% for i in app_config | dict_path %}
{{ i.0 | join('.') }} = {{ i.1 }}
{% endfor %}
皮埃尔