API响应中的Ansible拉取数据

时间:2018-12-19 18:19:49

标签: ansible json-query

我正在尝试使用API​​的JSON响应来查找要使用主机名备份的VM的UUID。 API返回一个哈希列表,其中包括主机名和该主机名的UUID。我想让Ansible在提供主机名时返回计算机的UUID。

这是API响应的示例,我将其存储在networker_vms中

    {
        "networker_vms.json.vms": [
            {
                "hostname": ""
            },
            {
                "hostname": ""
            },
            {
                "hostname": "server1.company.com",
                "uuid": "1ef92350-a5e3-8df3-6106-208a88aad352"
            },
            {
                "hostname": "server2.company.com",
                "uuid": "5003006d-23f4-a515-3722-181238489896"
            },
            {
                "hostname": "server3.company.com",
                "uuid": "50640076-07ae-571d-5e69-2183db42d2ee"
            },
            {
                "hostname": "server4.company.com",
                "uuid": "500410b1-505a-7539-5efd-89131d671b0a"
            },
            {
                "hostname": "server5.company.com",
                "uuid": "5024014b-e788-12a9-bcf6-5475ae50bf7c"
            },
            {
                "hostname": "server6.company.com",
                "uuid": "51462200-1abf-1c09-5007-fa72f76854fc"
            }
      ],
}

我可以使用以下Ansible代码段获取与主机名一致的UUID,但是将“ mynames”变量切换为类似{{ansible_hostname}}的代码时,我无法使代码正常工作-我收到错误消息“模块执行期间发生意外故障”。我想这与花括号的堆叠有关,但不确定。...

- name: debug my_uuid
  debug:
    msg: "{{ mynames | map('extract', dict(networker_vms.json | json_query('vms[].[hostname,uuid]'))) }}"
  vars:
    mynames:
      - server2.company.com

对于我来说,搜索API调用结果中特定主机名的最佳方法是什么,让Ansible为我将相应的uuid放入事实或变量中?

谢谢!

1 个答案:

答案 0 :(得分:0)

听起来像您要提取当前主机的UUID(由#ifdef __cplusplus extern "C" { #endif void grid_create(void); #ifdef __cplusplus } #endif 变量标识)。您可以这样做:

ansible_hostname

这只是将示例中的- name: debug using ansible_hostname debug: msg: >- {{ [ansible_hostname] | map('extract', dict(networker_vms.json | json_query('vms[].[hostname,uuid]'))) | first }} 替换为列表中的mynames,而[ansible_hostname]也是一个列表(由一个值组成,即ansible_hostname的内容)。这提供了map过滤器所必需的列表上下文。

但是,如果只有一个值,则无需使用map过滤器;您可以改为:

- name: debug using ansible_hostname
  debug:
    msg: >-
      {{ (networker_vms.json.vms |
      selectattr('hostname', 'eq', ansible_hostname)|first).uuid }}

更新

如果混合使用合格和不合格的主机名,则可以执行以下操作:

- name: get my uuid
  set_fact:
    my_uuid: "{{ host_to_addr[item] }}"
  when: my_uuid is not defined and item in host_to_addr
  vars:
    host_to_addr: "{{ dict(networker_vms.json | json_query('vms[].[hostname,uuid]')) }}"
  loop:
    - "{{ ansible_hostname }}"
    - "{{ ansible_fqdn }}"

- debug:
    var: my_uuid

这将遍历主机名列表,并将my_uuid事实设置为最先匹配的那个。

您还可以为json_query过滤器写一个稍微复杂的表达式:

- name: get my uuid
  debug:
    msg: >-
      {{ networker_vms.json.vms |
      json_query('[?hostname == `%s` || hostname == `%s`].[uuid]|[]' % (
      ansible_hostname, ansible_fqdn))|
      first}}