Ansible查询如何查询内部JSON输出

Ansible查询如何查询内部JSON输出,json,parsing,ansible,vmware,vcenter,Json,Parsing,Ansible,Vmware,Vcenter,我请求一个URL API并将其传递到寄存器的输出。这应该是一个JSON输出。 第一个变量“vcclust”JSON,我可以提取“item.cluster”,因为它只是一个级别,第二个输出“vchosts”看起来很糟糕,我无法解析从中获取“item.name”并获取主机名 代码如下: - hosts: localhost gather_facts: False vars_prompt: - name: "vcenter_hostname" prompt: "Enter vcen

我请求一个URL API并将其传递到寄存器的输出。这应该是一个JSON输出。 第一个变量“vcclust”JSON,我可以提取“item.cluster”,因为它只是一个级别,第二个输出“vchosts”看起来很糟糕,我无法解析从中获取“item.name”并获取主机名

代码如下:

- hosts: localhost
  gather_facts: False
  vars_prompt:
  - name: "vcenter_hostname"
    prompt: "Enter vcenter hostname"
    private: no
  - name: "vcenter_user"
    prompt: "Enter vcenter username"
    private: no
  - name: "vcenter_pass"
    prompt: "Enter vcenter password"
    private: yes
  - name: "cluster_touched"
    prompt: "Enter cluster name"
    private: no

  tasks:
  - name: Login in to vCenter and store login information
    uri:
      url: "https://{{ vcenter_hostname }}/rest/com/vmware/cis/session"
      force_basic_auth: yes
      method: POST
      user: '{{ vcenter_user }}'
      password: '{{ vcenter_pass }}'
      status_code: 200
      validate_certs: no
    register: login
  - name: Get vCenter cluster ID for {{ cluster_touched }}
    uri:
      url: "https://{{ vcenter_hostname }}/rest/vcenter/cluster?filter.names={{ cluster_touched }}"
      force_basic_auth: yes
      validate_certs: no
      headers:
        Cookie: '{{ login.set_cookie }}'
    register: vcclust
  - name: Get ESXi nodes from cluster ID for {{ cluster_touched }}
    uri:
      url: "https://{{ vcenter_hostname }}/rest/vcenter/host?filter.clusters={{ item.cluster }}"
      force_basic_auth: yes
      validate_certs: no
      headers:
        Cookie: '{{ login.set_cookie }}'
    register: vchosts
    with_items:
    - '{{ vcclust.json.value }}'
  - name: Modify root local user to ESXi
    vmware_local_user_manager:
      hostname: '{{ item.name }}'
      username: root
      password: '{{ esxi_pass }}'
      local_user_name: root
      local_user_password: '{{ esxi_new_pass }}'
      validate_certs: False
    with_items:
    - '{{ vchosts.json.value }}'
这是调试vchosts和vcclust的输出

vClust:

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "vcclust": {
        "changed": false,
        "connection": "close",
        "content_type": "application/json",
        "cookies": {},
        "date": "Mon, 11 Jun 2018 09:50:43 GMT",
        "failed": false,
        "json": {
            "value": [
                {
                    "cluster": "domain-c310",
                    "drs_enabled": true,
                    "ha_enabled": false,
                    "name": "DB-CLUSTER"
                }
            ]
        },
        "msg": "OK (unknown bytes)",
        "redirected": false,
        "status": 200,
        "url": "https://vcenter01.lab.test/rest/vcenter/cluster?filter.names=DB-CLUSTER"
    }
}
虚拟主机:

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "vchosts": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "_ansible_ignore_errors": null,
                "_ansible_item_result": true,
                "_ansible_no_log": false,
                "_ansible_parsed": true,
                "changed": false,
                "connection": "close",
                "content_type": "application/json",
                "cookies": {},
                "date": "Mon, 11 Jun 2018 09:50:45 GMT",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "attributes": null,
                        "backup": null,
                        "body": null,
                        "body_format": "raw",
                        "client_cert": null,
                        "client_key": null,
                        "content": null,
                        "creates": null,
                        "delimiter": null,
                        "dest": null,
                        "directory_mode": null,
                        "follow": false,
                        "follow_redirects": "safe",
                        "force": false,
                        "force_basic_auth": true,
                        "group": null,
                        "headers": {
                            "Cookie": "vmware-api-session-id=56fa6d3015150212b086917d15165bee;Path=/rest;Secure;HttpOnly"
                        },
                        "http_agent": "ansible-httpget",
                        "method": "GET",
                        "mode": null,
                        "owner": null,
                        "regexp": null,
                        "remote_src": null,
                        "removes": null,
                        "return_content": false,
                        "selevel": null,
                        "serole": null,
                        "setype": null,
                        "seuser": null,
                        "src": null,
                        "status_code": [
                            200
                        ],
                        "timeout": 30,
                        "unsafe_writes": null,
                        "url": "https://vcenter01.lab.test/rest/vcenter/host?filter.clusters=domain-c310",
                        "url_password": null,
                        "url_username": null,
                        "use_proxy": true,
                        "validate_certs": false
                    }
                },
                "item": {
                    "cluster": "domain-c310",
                    "drs_enabled": true,
                    "ha_enabled": false,
                    "name": "DB-CLUSTER"
                },
                "json": {
                    "value": [
                        {
                            "connection_state": "CONNECTED",
                            "host": "host-312",
                            "name": "vmh19.lab.test",
                            "power_state": "POWERED_ON"
                        },
                        {
                            "connection_state": "CONNECTED",
                            "host": "host-313",
                            "name": "vmh20.lab.test",
                            "power_state": "POWERED_ON"
                        }
                    ]
                },
                "msg": "OK (unknown bytes)",
                "redirected": false,
                "status": 200,
                "url": "https://vcenter01.lab.test/rest/vcenter/host?filter.clusters=domain-c310"
            }
        ]
    }
}
我得到的错误是:

ansible (ansible_test) ✗)ansible-playbook site.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

Enter vcenter hostname [vcenter01.lab.test]: 
Enter vcenter username : 
Enter vcenter password : 
Enter cluster name [DB-CLUSTER]: 

PLAY [localhost] *********************************************************************************************************************************************************************************************

TASK [Start SSH service setting for an ESXi Host in given Cluster] *******************************************************************************************************************************************
ok: [localhost]

TASK [Login in to vCenter and store login information] *******************************************************************************************************************************************************
ok: [localhost]

TASK [Get vCenter cluster ID for DB-CLUSTER] *************************************************************************************************************************************************************
ok: [localhost]

TASK [Get ESXi nodes from cluster ID for DB-CLUSTER] *****************************************************************************************************************************************************
ok: [localhost] => (item={'drs_enabled': True, 'cluster': 'domain-c310', 'name': 'DB-CLUSTER', 'ha_enabled': False})

TASK [Modify root local user to ESXi] ************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "'dict object' has no attribute 'json'"}
    to retry, use: --limit @/Users/jv/Workspace/vmware-powershell/ansible/site.retry

PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=1 

我做错了什么?

尝试使用
json\u查询。为此,您可能需要在ansible主机上安装
jmespath
。您可以使用
pip安装jmespath
来完成

 - name: Get ESXi nodes from cluster ID for {{ cluster_touched }}
    uri:
      url: "https://{{ vcenter_hostname }}/rest/vcenter/host?filter.clusters={{ item.cluster }}"
      force_basic_auth: yes
      validate_certs: no
      headers:
        Cookie: '{{ login.set_cookie }}'
    register: vchosts
    with_items: "{{ vcclust | json_query('*.value') }}"

  - name: Modify root local user to ESXi
    vmware_local_user_manager:
      hostname: '{{ item.name }}'
      username: root
      password: '{{ esxi_pass }}'
      local_user_name: root
      local_user_password: '{{ esxi_new_pass }}'
      validate_certs: False
    with_items: "{{ vchosts.results | json_query('*.value') }}"

非常感谢@Kelson Silva

你指出了答案的线索

我不知道为什么会这样

- debug: var=item.name
    with_items:
    -  "{{ vchosts.json.value }}"
不一样

- debug: 
    var: item.name
    with_items:
    -  "{{ vchosts.json.value }}"
事实上,这让我抓狂,这肯定是ansible版本中的一个bug

问题是,它将我的第一个请求中的元素作为Json中的列表发送,您需要枚举它们

为了不获取脏的“vchosts”JSON,您只需要使用“vcclust”中的一个元素,因此代码结尾如下:

  - name: Get vCenter cluster ID for {{ cluster_touched }}
    uri:
      url: "https://{{ vcenter_hostname }}/rest/vcenter/cluster?filter.names={{ cluster_touched }}"
      force_basic_auth: yes
      validate_certs: no
      headers:
        Cookie: '{{ login.set_cookie }}'
    register: vcclust

  - name: Get ESXi nodes from cluster ID for {{ cluster_touched }}
    uri:
      url: "https://{{ vcenter_hostname }}/rest/vcenter/host?filter.clusters={{ vcclust.json.value[0].cluster }}"
      force_basic_auth: yes
      validate_certs: no
      headers:
        Cookie: '{{ login.set_cookie }}'
    register: vchosts

  - name: Modify root local user to ESXi
    vmware_local_user_manager:
      hostname: '{{ item.name }}'
      username: root
      password: '{{ esxi_pass }}'
      local_user_name: root
      local_user_password: '{{ esxi_new_pass }}'
      validate_certs: False
    with_items:
    -  "{{ vchosts.json.value }}"

我尝试了使用{u items:-{{vchosts.results.json.value}}},但结果是一样的,所以我尝试了检查-debug:var:{{item.name}}中的值,使用{u items:-“{vchosts}json|u查询('*.value')}”任务[debug]男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生***任务[将根本地用户修改为ESXi]******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************请尝试修改用户在该主机上的本地使用结果。我还编辑了我的原始答案。任务[将根本地用户修改为ESXi]***致命:[localhost]:失败!=>{“msg”:"该任务包含一个带有未定义变量的选项。错误是:“ansible.utils.safe\u proxy.AnsibleUnsafeText对象”没有属性“name”\n\n错误似乎出现在“/Users/jv/Workspace/vmware powershell/ansible/site.yml”:第70行第5列,但可能\n位于文件的其他位置,具体取决于语法问题。\n\n有问题行似乎是:\n\n\n-name:Modify root local user to ESXi\n^ here\n“}若要重试,请使用:--limit@/Users/jv/Workspace\vmware powershell/ansible/site.retryIf I try-debug:var:{{item.name}with_items:-“{vchosts.results}json|U查询('*.value')}”我得到了任务[debug]男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生男生***确定:[localhost]=>(item=None)=>{“msg”:“Hello world!”}在调试时使用var时,应该使用item.name,不带引号和“{{}}”“。当使用msg时,则使用“{item.name}”。您使用的是ansible的哪个版本?我在本地环境中进行了测试,它确实与vchost一起工作。结果。。。