【问题标题】:The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n该任务包括一个带有未定义变量的选项。错误是:“ansible.utils.unsafe_proxy.AnsibleUnsafeText 对象”没有属性“数据”\n
【发布时间】:2021-02-06 21:29:16
【问题描述】:

我有一个简单的剧本,使用 curl 从 Vault 服务器获取一些数据。

tasks:
    - name: role_id
      shell: 'curl \
             --header "X-Vault-Token: s.ddDblh8DpHkOu3IMGbwrM6Je" \
             --cacert vault-ssl-cert.chained \
             https://active.vault.service.consul:8200/v1/auth/approle/role/cpanel/role-id'
      register: 'vault_role_id'
    - name: test1
      debug:
        msg: "{{ vault_role_id.stdout }}"

输出是这样的:

TASK [test1] *********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "auth": null,
        "data": {
            "role_id": "65d02c93-689c-eab1-31ca-9efb1c3e090e"
        },
        "lease_duration": 0,
        "lease_id": "",
        "renewable": false,
        "request_id": "8bc03205-dcc2-e388-57ff-cdcaef84ef69",
        "warnings": null,
        "wrap_info": null
    }
}

如果我正在访问第一级属性,一切正常,例如前面示例中的 .stdout。我需要更深层次的属性才能达到,比如vault_role_id.stdout.data.role_id。当我尝试这个时,它失败并出现以下错误:

"The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n\n

您有什么建议可以从这个对象层次结构的更深层次正确获取属性值吗?

【问题讨论】:

  • 过滤curl的输出。例如 curl ... | jq '.'Display curl output in readable JSON format in Unix shell script.
  • 我试过了,但没有更好的。在没有过滤的情况下,我也有 json 格式的输出,就像我在上面粘贴的那样。但是,由于某种原因,无法从对象结构中的 dipper 级别到达属性,然后是第一级,在我的示例中是 .stdout ...

标签: dictionary ansible


【解决方案1】:

“任务包含一个带有未定义变量的选项。错误是:'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n\n

是的,因为正在发生的事情是使用{{ 将其渲染为msg:强制将JSON 文本 转换为python dict;如果您确实希望它成为dict,则使用msg: "{{ (vault_role_id.stdout | from_json).data.role_id }}",或者您可以使用set_fact: {vault_role_data: "{{vault_role_id.stdout}}"},然后vault_role_data 将成为dict,原因与您的msg 强制使用的原因相同

你可以通过在 msg 前面加上任何字符来查看相反的过程:

- name: this one is text
  debug:
    msg: vault_role_id is {{ vault_role_id.stdout }}
- name: this one is coerced
  debug:
    msg: '{{ vault_role_id.stdout }}'

虽然这不是您所要求的,但您还应该将 --fail 添加到您的 curl 以便在请求返回非 200-OK 时它以非零返回码存在,或者您可以使用更多ansible-y 方式通过- uri: 并设置return_content: yes 参数

【讨论】:

  • 谢谢 mdaniel,效果很好。我正要使用 uri,但遇到了验证 ssl 证书的问题,我不知道如何处理。使用 curl 证书验证工作正常 - 可能是因为它没有使用 python。 SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1123)
  • 他们可以选择suppress cert validation,但是是的,我认为实际上信任自签名的 Vault 需要通知 python 它是受信任的
  • 是的,有这样的选项。是的,这是 Vault 自签名证书。我相信当你说它需要通知 python 它是可信的时你又是对的。我将使用非 Vault 但常规的、通常受信任的证书对此进行测试。谢谢你!
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
相关资源
最近更新 更多