我正在构建一组Anable任务,使用它们的API通过Namecheap续订HTTPS证书.他们的API返回XML响应,所以我一直在使用Ansible Community ity.General al.xml模块来解析我从每个响应中需要的内容.其中一项任务是连接每个中间证书以构建证书链文件,但Ansible模块返回的属性名包括特殊字符以指示XML名称空间.
以下是来自Namecheap API端点的示例响应.我正在try 获取三个<Certificate>
node ,每个 node 都在其自己的<Certificate Type="INTERMEDIATE">
node 内.
<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
<Errors/>
<Warnings/>
<RequestedCommand>namecheap.ssl.getInfo</RequestedCommand>
<CommandResponse Type="namecheap.ssl.getInfo">
<SSLGetInfoResult Status="active" StatusDescription="Certificate is Active." Type="EssentialSSL Wildcard" IssuedOn="9/8/2022" Years="1" Expires="9/22/2023" ActivationExpireDate="" OrderId="1234567890" SANSCount="0">
<CertificateDetails>
<CSR>
<![CDATA[-----BEGIN CERTIFICATE REQUEST----- ... -----END CERTIFICATE REQUEST-----]]>
</CSR>
<ApproverEmail>CNAMECSRHASH</ApproverEmail>
<CommonName>*.example.com</CommonName>
<AdministratorEmail>example@example.com</AdministratorEmail>
<Certificates CertificateReturned="true" ReturnType="INDIVIDUAL">
<Certificate>
<![CDATA[-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----]]>
</Certificate>
<CaCertificates>
<Certificate Type="INTERMEDIATE">
<Certificate>
<![CDATA[-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----]]>
</Certificate>
</Certificate>
<Certificate Type="INTERMEDIATE">
<Certificate>
<![CDATA[-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----]]>
</Certificate>
</Certificate>
<Certificate Type="INTERMEDIATE">
<Certificate>
<![CDATA[-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----]]>
</Certificate>
</Certificate>
</CaCertificates>
</Certificates>
</CertificateDetails>
<Provider>
<OrderID>1234567890</OrderID>
<Name>COMODO</Name>
</Provider>
</SSLGetInfoResult>
</CommandResponse>
<Server>e4fee023b712</Server>
<GMTTimeDifference>--5:00</GMTTimeDifference>
<ExecutionTime>0.117</ExecutionTime>
</ApiResponse>
这是我目前正在处理的一组可分析任务的"基线".
- name: parse info response for cert chain
community.general.xml:
xmlstring: "{{ namecheap_info.content }}"
namespaces:
x: 'http://api.namecheap.com/xml.response'
xpath: '/x:ApiResponse/x:CommandResponse/x:SSLGetInfoResult/x:CertificateDetails/x:Certificates/x:CaCertificates/x:Certificate/x:Certificate'
content: text
register: parsed_cert_chain
- ansible.builtin.set_fact:
namecheap_cert_chain_content: "{{ parsed_cert_chain.matches | map(attribute='{http://api.namecheap.com/xml.response}Certificate') }}"
当我运行这些任务时,我从ansible.Builtin.set_act模块得到一个错误:The task includes an option with an undefined variable. The error was: 'dict object' has no attribute '{http://api'.
.我知道这是因为URL中的句点被视为属性访问器,但我还没有成功地弄清楚如何转义它.
以下是我try 过的一些方法(请注意,其中一些只是在黑暗中拍摄)及其各自的错误消息:
- 在句点(
'dict object' has no attribute '{http://api\\\\'.
)上使用反斜杠 - 句点上的双反斜杠(
'dict object' has no attribute '{http://api\\\\\\\\'.
) - 大括号上的反斜杠(
'dict object' has no attribute '\\\\{http://api'.
) - 使用方括号将字符串括起来(请参见https://stackoverflow.com/a/55223203)(
dict object has no element ['{http://api.namecheap.com/xml.response}Certificate'].
) - try 字符串内侧的方括号(
'dict object' has no attribute '[{http://api'.
)
我想我可以在将字符串传递到XML模块之前使用替换过滤器从字符串中删除XML名称空间,但这感觉有点像创可贴.转义map(attribute)
JJAA2过滤器的特殊字符的正确方法是什么?