从set_fact返回与var相同的数据

时间:2019-04-23 10:54:30

标签: ansible jinja2 ansible-facts

我正在尝试创建字典。使用var时,一切正常。但是Set_fact就像是被忽略的东西,我无法隔离。

阅读Jinja2手册,多次迭代

---
- hosts: localbox   gather_facts: false

  vars:
      app_servers: 5
      ipaddress_base: "192.168.0"
      rmi_portbase: 10000
      host_info: |
        {% set res = [] -%}
        {%- for number in range(1,app_servers + 1) -%}
          {% set ignored = res.extend([{
            'hostname': 'app' + number|string,
            'ipaddress': ipaddress_base + '.' + number|string,
            'rmi_port': rmi_portbase|int + ( number * 10)
            }]) -%}
        {%- endfor %}
        {{ res }}

  tasks:

    - name: thing
      set_fact: 
        thing2: "{% set res = [] -%}
        {%- for number in range(1,app_servers + 1) -%}
          {% set ignored = res.extend([{
            'hostname': 'app' + number|string,
            'ipaddress': ipaddress_baase + '.' + number|string,
            'rmi_port': rmi_portbase|int + ( number * 10)
            }]) -%}
        {%- endfor %}
        {{ res }}"

    - debug: var=host_info[0].hostname
    - debug: var=thing2[0]

我希望来自Thing2的结果类似于host_info。

TASK [debug] *******************************************************************
ok: [localhost] => {
    "host_info[0].hostname": "app1"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "thing2[0]": " "
}

1 个答案:

答案 0 :(得分:1)

如果您运行发布的剧本,它将失败并显示以下错误:

  

任务[事物]

     
     

致命:[localhost]:失败! => {“ msg”:“该任务包括一个选项   具有未定义的变量。错误是:“ ipaddress_baase”为   未定义\ n \ n错误似乎出在'/ home / lars /   tmp / ansible / playbook.yml':第25行第7列,但可能\在   文件,具体取决于确切的语法问题。\ n \ n违规行   似乎是:\ n \ n \ n-名称:thing \ n ^她的e \ n“}

确实,您将ipaddress_base拼写为ipaddress_baase(请注意额外的a)。如果您修正了该错字并添加,请修改最终的debug任务,如下所示:

- debug: var=thing2

您应该看到以下输出:

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "thing2": " [{'rmi_port': 10010, 'hostname': u'app1', 'ipaddress': u'192.168.0.1'}, {'rmi_port': 10020, 'hostname': u'app2', 'ipaddress': u'192.168.0.2'}, {'rmi_port': 10030, 'hostname': u'app3', 'ipaddress': u'192.168.0.3'}, {'rmi_port': 10040, 'hostname': u'app4', 'ipaddress': u'192.168.0.4'}, {'rmi_port': 10050, 'hostname': u'app5', 'ipaddress': u'192.168.0.5'}]"
}

向我们显示的是thing2是字符串,而不是字典。因此,当您为thing2[0]分配任务时,您将在该字符串的位置0处获得字符。

原因是一个字符串,而不是字典是因为是索引0处的前导空格。我们可以通过更改{{1 }}语句从endfor%},它将占用以下任何空白:

-%}

完成此任务和您最初的- set_fact: thing2: "{% set res = [] -%} {%- for number in range(1,app_servers + 1) -%} {% set ignored = res.extend([{ 'hostname': 'app' + number|string, 'ipaddress': ipaddress_baase + '.' + number|string, 'rmi_port': rmi_portbase|int + ( number * 10) }]) -%} {%- endfor -%} {{ res }}" 任务,我们将其视为输出:

debug

话虽如此,我将停止尝试使用这种技术来生成复杂的数据结构,因为正如我们所看到的那样,它容易出错。我会这样写:

TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "host_info[0].hostname": "app1"
}

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "thing2[0]": {
        "hostname": "app1", 
        "ipaddress": "192.168.0.1", 
        "rmi_port": 10010
    }
}

我认为这既易于实现,又易于阅读。