Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 使用map()函数根据Jinja2/Ansible中的唯一键连接两个dict列表_Templates_Dictionary_Ansible_Jinja2 - Fatal编程技术网

Templates 使用map()函数根据Jinja2/Ansible中的唯一键连接两个dict列表

Templates 使用map()函数根据Jinja2/Ansible中的唯一键连接两个dict列表,templates,dictionary,ansible,jinja2,Templates,Dictionary,Ansible,Jinja2,我将陈述最终目标,以防有人有更好的想法。我正在尝试使用ansible在nagios中设置主机监视。我希望使用变量集合来定义某些服务的默认值,并使这些变量能够被更具体的变量覆盖 因此,我最终得到了两个dict列表,希望第一个列表是默认列表,并将其与第二个列表合并,其中dict位于第二个列表中,匹配的键名具有优先权 list1: [ {u'type': u'local-service', u'command': u'something', u'name': u'AUTODISCOVER'}, {u

我将陈述最终目标,以防有人有更好的想法。我正在尝试使用ansible在nagios中设置主机监视。我希望使用变量集合来定义某些服务的默认值,并使这些变量能够被更具体的变量覆盖

因此,我最终得到了两个dict列表,希望第一个列表是默认列表,并将其与第二个列表合并,其中dict位于第二个列表中,匹配的键名具有优先权

list1: [
{u'type': u'local-service', u'command': u'something', u'name': 
u'AUTODISCOVER'},
{u'type': u'pager-service', u'command': u'something', 
u'name': u'RPC'},
{u'type': u'local-service', u'command': u'something', u'name': u'PING''} ]

list2: [
{u'type': u'local-service', u'command': u'different', u'name': u'AUTODISCOVER'} ]
由此产生的清单将是:

list: [
{u'type': u'local-service', u'command': u'different', u'name': u'AUTODISCOVER'},
{u'type': u'pager-service', u'command': u'something', u'name': u'RPC'},
{u'type': u'local-service', u'command': u'something', u'name': u'PING''} ]
在我的jinja2模板中,我有以下内容:

{% set services = item.services | union( server_types[item.type].services ) %}
{% for service in services | sort(attribute='name') %}
{{ service.name }}
{% endfor %}
上面是一些调试输出 这将正常工作并列出已排序的服务名称属性

{% for service in services | map(attribute='name') | list | unique %}
define  service{
    use                   {{ service.type | default('local-service') }}
    host_name             {{ item.host }}
    service_description   {{ service.name }}
    check_command         {{ service.command }}
}
{% endfor %}
这导致了这个错误

AnsibleUndefinedVariable: 'unicode object' has no attribute 'name'
因此,很明显,它正在将dict对象转换为字符串,并试图映射它,这导致了错误。但是看看这些文档,我的语法似乎是正确的,它在第一个循环的sort()过滤器中充当dict对象。那么为什么map函数在第二个循环中对我来说失败了呢?

从评论中回答:

services | map(attribute='name')| list
仅从
services
列表中的每个元素中获取
name
属性,并形成一个新列表


services | map(attribute='name')| list
仅从
services
列表中的每个元素中获取
name
属性,并形成一个新列表。谢谢。我做了更多的测试,你是对的。我相信定制的jinja2过滤器是正确的方法。如果您将此作为答案发布,我会将其标记为正确,因为它确实回答了问题。谢谢,为了澄清,映射筛选器返回由属性指定的键的值的列表,并且不是错误的原因。错误实际上来自这一行:“service_description{{{service.name}}”,因为循环的列表现在只是字符串列表,而不是完整的dict。我把它弄糊涂了,因为service.type会抛出错误,除非我指定了一个默认值,以防它没有定义。谢谢你的帮助!