使用 Ansible 中大括号括起来的键访问项目的字典值

Accessing dict value for item with a key that is enclosed in braces in Ansible

运行 进入访问字典值的问题,因为它有一个非常奇怪的键。我使用 xml 模块过滤名称空间来设置这个对象,然后设置一个等于返回的匹配值的事实。如果有 better/easier 方法可以做到这一点,我会喜欢的,因为我很困惑。

示例XML:

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/id">
    <md:IDPSSODescriptor WantAuthnRequestsSigned="false"
        protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>thisisfakedata</ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </md:KeyDescriptor>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
            Location="https://login.company.com/app/app/id/sso/saml" />
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            Location="https://login.company.com/app/app/id/sso/saml" />
    </md:IDPSSODescriptor>
</md:EntityDescriptor>

这是我对命名空间和 XML 模块的使用:

- name: "Search for cert in metadata"
  xml:
    xmlstring: "{{ cert }}"
    xpath: /x:EntityDescriptor/x:IDPSSODescriptor/x:KeyDescriptor/y:KeyInfo/y:X509Data/y:X509Certificate
    namespaces:
      x: urn:oasis:names:tc:SAML:2.0:metadata
      y: http://www.w3.org/2000/09/xmldsig#
    content: text
  register: xml_xpath_result

注册结果如下所示:

{
    "actions": {
        "namespaces": {
            "x": "urn:oasis:names:tc:SAML:2.0:metadata",
            "y": "http://www.w3.org/2000/09/xmldsig#"
        },
        "state": "present",
        "xpath": "/x:EntityDescriptor/x:IDPSSODescriptor/x:KeyDescriptor/y:KeyInfo/y:X509Data/y:X509Certificate"
    },
    "changed": false,
    "count": 1,
    "matches": [{
        "{http://www.w3.org/2000/09/xmldsig#}X509Certificate": "thisisfakedata"
    }],
    "msg": 1,
    "xmlstring": "seexml"
}

如果我随后尝试将事实设置为匹配列表中该键的值,则它不起作用。我尝试了多种方法,最近将事实设置为 obj.matches[0] 然后尝试打印“{{ fact.{http://www.w3.org/2000/09/xmldsig#}X509Certificate }}”,我遇到了问题。请参阅下面的错误。有什么我可以做的来完成这项工作,要么转义它们的密钥以使其正常工作,要么通过更改我对 xml 模块的使用以获得更正常的密钥?我正在努力避免对它的破坏超过它已经感觉到的程度。

- name: "set idp cert"
  set_fact:
    idp_app_cert: "{{ xml_xpath_result.matches[0] }}"
  when: xml_xpath_result is defined

- debug:
    msg: "{{ idp_app_cert.{http://www.w3.org/2000/09/xmldsig#}X509Certificate }}"

错误:

TASK [pbname : debug] ********************************************************************************************************************
task path: ~tasks/main.yml:40
fatal: [localhost]: FAILED! => {"msg": "template error while templating string: expected name or number. String: {{ idp_app_cert.{http://www.w3.org/2000/09/xmldsig#}X509Certificate }}"}

为了清楚起见,这里的最终结果只是简单地设置一个事实值:thisisfakedata

通过以不同方式访问我的密钥并在其周围添加单引号来解决此问题。留下这个以防其他人遇到类似的情况..

- debug:
    msg: "{{ idp_app_cert['{http://www.w3.org/2000/09/xmldsig#}X509Certificate'] }}"
TASK [pbname : debug] ********************************************************************************************************************
task path: ~/tasks/main.yml:40
ok: [localhost] => {
    "msg": "thisisfakedata"
}