遇到“dict object”时,Ansible没有属性“results”,尽管之前的检查表明它确实存在

2024-06-14 18:59:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Ansible,遇到了一个我不理解或不知道如何解决的问题。希望有人能帮助我

问题发生在failed_when条件中:

fatal: [localhost]: FAILED! => {
    "msg": "The conditional check ''must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']' failed. The error was: error while evaluating conditional ('must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']): 'dict object' has no attribute 'results'"
}

我的任务是:

  - name: Create instance - must not contain special characters or whitespace
    uri:
     url: "https://{{PROXY_ADDRESS}}/api/sol005/etsi/nslcm/v2/ns_instances"
     status_code: 400
     validate_certs: no
     body_format: json
     method: POST
     headers:
      Content-type: application/json
      Authorization: "{{'Bearer'+' '+access_token}}"
      Version: "2.0.0"
      Accept: "*/*"
     body: >
           { "nsdId": "instance::int::1.0",
             "nsName": "{{ item }}",
             "nsDescription": "Test instance with name containing invalid characters."
           }
    register: result
#  - set_fact:
#      localizedMessage: "{{ result.results[0].json['localizedMessage'] }}"
    with_items:
      - "caesar:test"
    failed_when: "'must not contain special characters or whitespace' not in result.results[0].json['localizedMessage']"

在尝试调试时,我编写了以下内容:

 - debug:
      msg:
        - "============ Printing result output ============"
        - "Showing result type: {{ result | type_debug }}"
        - "Showing result contents: {{ result}}"
        - "Showing result.keys(): {{ item }}"
    with_items: "{{ result.keys() }}"
  - debug:
      msg:
        - "============ Printing result.results output ============"
        - "Showing result.results type: {{ result.results | type_debug }}"
        - "Showing result.results contents: {{ result.results }}"
  - debug:
      msg:
        - "============ Printing result.results[0] output ============"
        - "Showing result.results[0].type: {{ result.results[0] | type_debug }}"
        - "Showing result.results[0].contents: {{ result.results[0] }}"
        - "Showing result.results[0].keys(): {{ item }}"
    with_items: "{{ result.results[0].keys() }}"
  - debug:
      msg:
        - "============ Printing result.results[0].json output ============"
        - "Showing result.results[0].json type: {{ result.results[0].json | type_debug }}"
        - "Showing result.results[0].json contents: {{ result.results[0].json }}"
        - "Showing result.results[0].json.keys(): {{ item }}"
    with_items: "{{ result.results[0].json.keys() }}"
  - debug:
      msg:
        - "============ Printing result.results[0].json.localizedMessage output ============"
        - "Showing result.results[0].json.localizedMessage type: {{ result.results[0].json.localizedMessage | type_debug }}"
        - "Showing result.results[0].json.localizedMessage contents: {{ result.results[0].json.localizedMessage }}"

我认为,这里的重要信息是:

        "============ Printing result output ============",
        "Showing result type: dict",
        "Showing result.keys(): dict_keys(['results', 'msg', 'changed'])"

       "============ Printing result.results output ============",
        "Showing result.results type: list",

        "============ Printing result.results[0] output ============",
        "Showing result.results[0].type: dict",
        "Showing result.results[0].keys(): dict_keys(['redirected', 'url', 'status', 'x_content_type_options', 'x_xss_protection', 'cache_control', 'pragma', 'expires', 'strict_transport_security', 'x_frame_options', 'vary', 'content_type', 'transfer_encoding', 'date', 'connection', 'server', 'msg', 'elapsed', 'changed', 'json', 'invocation', 'failed', 'item', 'ansible_loop_var'])"

        "============ Printing result.results[0].json output ============",
        "Showing result.results[0].json type: dict",
        "Showing result.results[0].json.keys(): dict_keys(['url', 'localizedMessage', 'details'])"

        "============ Printing result.results[0].json.localizedMessage output ============",
        "Showing result.results[0].json.localizedMessage type: AnsibleUnsafeText",
        "Showing result.results[0].json.localizedMessage contents: A INVALID_REQUEST error has occurred: name must not contain special characters or whitespace (excluding: '-', '_')"

我不熟悉Ansible,也许这就是我没有看到它的原因,但是用'dict object' has no attribute 'results'这个词表示result,这是一个dict,没有我调试时建议的results属性。 我已经能够穿越到result.results[0].json&result.results[0].json.localizedMessage所以我觉得还可以

有人能提供建议吗?我想了解我哪里出了问题,或者我会采取其他方法执行failed_when检查的建议


Tags: debugjsonoutputtypecontentsnotmsgresult
1条回答
网友
1楼 · 发布于 2024-06-14 18:59:08

您的问题来自Ansible以一种非常独特的方式创建results

  1. 这些项的注册就好像您根本不使用循环一样,您可以通过注册的变量引用前面的元素
  2. 当存在循环时,将在字典中创建results键,然后根据所有结果填充该键

这在这句话和例子中用非常简短的方式描述:

During iteration, the result of the current item will be placed in the variable:

- name: Place the result of the current item in the variable
  shell: echo "{{ item }}"
  loop:
    - one
    - two
  register: echo
  changed_when: echo.stdout != "one"

来源:https://docs.ansible.com/ansible/2.9/user_guide/playbooks_loops.html#registering-variables-with-a-loop


因此,如果您想要一个自注册的任务来检查其自身的项目状态,您只需执行以下操作:

failed_when: "'must not contain special characters or whitespace' not in result.json.localizedMessage"

以下是两个示例剧本:

  1. 剧本
    - hosts: localhost
      gather_facts: no
    
      tasks:
        - uri:
            url: "{{ item }}"
          loop:
            - https://httpbin.org/get
            - https://httpbin.org/anything
          register: result
          failed_when: "result.json.url == 'https://httpbin.org/get'"
    
    这就产生了重述:
    PLAY [localhost] ***************************************************************************************************
    
    TASK [uri] *********************************************************************************************************
    failed: [localhost] (item=https://httpbin.org/get) => {"access_control_allow_credentials": "true", "access_control_allow_origin": "*", "ansible_loop_var": "item", "changed": false, "connection": "close", "content_length": "274", "content_type": "application/json", "cookies": {}, "cookies_string": "", "date": "Fri, 18 Dec 2020 18:17:12 GMT", "elapsed": 0, "failed_when_result": true, "item": "https://httpbin.org/get", "json": {"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "ansible-httpget", "X-Amzn-Trace-Id": "Root=1-5fdcf228-559950431b1315ce1ea53e71"}, "url": "https://httpbin.org/get"}, "msg": "OK (274 bytes)", "redirected": false, "server": "gunicorn/19.9.0", "status": 200, "url": "https://httpbin.org/get"}
    ok: [localhost] => (item=https://httpbin.org/anything)
    
    PLAY RECAP *********************************************************************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
    
  2. 剧本
    - hosts: localhost
      gather_facts: no
    
      tasks:
        - uri:
            url: "{{ item }}"
          loop:
            - https://httpbin.org/get
            - https://httpbin.org/anything
          register: result
          failed_when: "result.json.url == 'https://httpbin.org/anything'"
    
    这就产生了重述:
    PLAY [localhost] ***************************************************************************************************
    
    TASK [uri] *********************************************************************************************************
    ok: [localhost] => (item=https://httpbin.org/get)
    failed: [localhost] (item=https://httpbin.org/anything) => {"access_control_allow_credentials": "true", "access_control_allow_origin": "*", "ansible_loop_var": "item", "changed": false, "connection": "close", "content_length": "362", "content_type": "application/json", "cookies": {}, "cookies_string": "", "date": "Fri, 18 Dec 2020 18:18:40 GMT", "elapsed": 0, "failed_when_result": true, "item": "https://httpbin.org/anything", "json": {"args": {}, "data": "", "files": {}, "form": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "ansible-httpget", "X-Amzn-Trace-Id": "Root=1-5fdcf280-71b7cca020b6fda0055b4603"}, "json": null, "method": "GET", "origin": "109.128.153.27", "url": "https://httpbin.org/anything"}, "msg": "OK (362 bytes)", "redirected": false, "server": "gunicorn/19.9.0", "status": 200, "url": "https://httpbin.org/anything"}
    
    PLAY RECAP *********************************************************************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
    

相关问题 更多 >