ansible - 如何正确地将变量放入 ansible j2 模板
问题描述
我在运行此任务时遇到 ansible j2 模板问题我使用此任务创建 grafana 数据源
- name: Get certifacete
slurp:
src: /var/lib/cloudera-scm-server/certmanager/CMCA/ca-db/newcerts/00.pem
register: cert
- name: test
uri:
url: https://127.0.0.1:3000/api/datasources
method: POST
validate_certs: no
force_basic_auth: yes
user: "{{ grafana_admin_user }}"
password: "{{ grafana_admin_password }}"
body: "{{ lookup('template', 'test_template.j2') }}"
body_format: json
headers:
Content-Type: "application/json"
模板
{
"name": "Cloudera Manager",
"type": "foursquare-clouderamanager-datasource",
"url":"https://{{ hostvars[groups['tag_Group_cm'][0]]['ec2_private_ip_address'] }}:7183",
"access":"proxy",
"isDefault":false,
"basicauth":true,
"basicAuthUser":"{{ managerUser }}",
"basicAuthPassword":"{{ managerPassword }}",
"jsonData": {
"cmAPIVersion":"{{ cmapi }}",
"tlsAuthWithCACert": true},
"secureJsonData":{
"tlsCACert": "{{ cert['content'] | b64decode | string }}"
},
"database": "foursquare-clouderamanager-datasource"}
当我将此模板与变量一起使用时出现此错误
fatal: [10.0.1.31]: FAILED! => {"cache_control": "no-cache", "changed": false, "connection": "close", "content": "[{\"classification\":\"DeserializationError\",\"message\":\"invalid character '\\\\\\\\' looking for beginning of object key string\"},{\"fieldNames\":[\"Name\"],\"classification\":\"RequiredError\",\"message\":\"Required\"},{\"fieldNames\":[\"Type\"],\"classification\":\"RequiredError\",\"message\":\"Required\"},{\"fieldNames\":[\"Access\"],\"classification\":\"RequiredError\",\"message\":\"Required\"}]", "content_length": "359", "content_type": "application/json; charset=utf-8", "date": "Thu, 14 Nov 2019 10:48:45 GMT", "elapsed": 0, "expires": "-1", "json": [{"classification": "DeserializationError", "message": "invalid character '\\\n' looking for beginning of object key string"}, {"classification": "RequiredError", "fieldNames": ["Name"], "message": "Required"}, {"classification": "RequiredError", "fieldNames": ["Type"], "message": "Required"}, {"classification": "RequiredError", "fieldNames": ["Access"], "message": "Required"}], "msg": "Status code was 400 and not [200]: HTTP Error 400: Bad Request", "pragma": "no-cache", "redirected": false, "status": 400, "strict_transport_security": "max-age=86400; preload", "url": "https://127.0.0.1:3000/api/datasources", "x_frame_options": "deny", "x_xss_protection": "1; mode=block"}
当我使用没有变量的模板时,没有变量的示例调试输出效果很好:
"body": {
"access": "proxy",
"basicAuthPassword": "passs",
"basicAuthUser": "user",
"basicauth": true,
"database": "foursquare-clouderamanager-datasource",
"isDefault": false,
"jsonData": {
"cmAPIVersion": "v4-5",
"tlsAuthWithCACert": true
},
"name": "Cloudera Manager",
"secureJsonData": {
"tlsCACert": "-----BEGIN CERTIFICATE-----\nMIIEmDCCAwCgAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJVUzEL\nMAkGA1UECAwCQ0ExQTA/BgNVBAMMOFNDTSBMb2NhbCBDQSBvbiBkZXBsb3ltZW50\nIGFicnluZHphLWRldi1kZXZsaWdodC1tYW5hZ2VyMB4XDTE5MTExNDA4NDYxOFoX\nDTQ5MTEwMTIzNTk1OVowXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMUEwPwYD\nVQQDDDhTQ00gTG9jYWwgQ0Egb24gZGVwbG95bWVudCBhYnJ5bmR6YS1kZXYtZGV2\nbGlnaHQtbWFuYWdlcjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAK5z\nQOfwxFUMbtMGsVNsheJRNx+8en7iyv4emUu2h7VBIwInzqd9qG3gpTjTHPmp/q/T\nnCi9peKT3EbhvCdbzUmyDX8oAHEIZ0ww+oVyz6omDcV9hkWWsm/JEOyZdP2/OLyb\nv4gdm03vfiZXN6/Xz8C8XZtpgM+pq9+aFK8bQuKE2M333xKqoWnPDlBeFXYKeDjZ\ndtR6OKmChXVViQdkXvhTaG48coBmIrDOCUwm1SMYmohltNSzpdfSgX3GSwVse3fM\nbnWlV/ITDjCkklBcJENn86M7Cb8z55gvwqAHD8Xoqmjt/rzS7hQDcUsG0Zy2cOkl\nuq6ClYpn3Gpm4nXU3bYEvpmiYMKo62wgUz2OC0IAWz4WGvoh0maCKtFnErvGkxkR\nS30Ayz5bPPud3m24gnW92uNcJRStVMrlmg/MdpBr+AiuWrImMX2d1kXBd2zh4L78\n1nk5ZCMyaO6kvnTez6cGc8YqJdFIy76Phw2qeEBhjPkA7+w/BVHSIs2eP79wIwID\nAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRmmdoZo1DrE6uSw1GT\n01061RzynTAfBgNVHSMEGDAWgBRmmdoZo1DrE6uSw1GT01061RzynTAOBgNVHQ8B\nAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggGBAHykOktg6mWPwAXh5RyCKLv+2bVQ\nrtAy4JkTiAsroURm+sdYqQ7KD61vfFI7V1twytOmohfbtJ/4qhcGrh1w1s7yv/a0\nbm7fcG7qViX3QoMaVrgs1wkUQC2JNcT9vPFjHcKA/YtvHVcoYYTPVvr+jS6sbh9e\nvTMu14klVyaqRlPsF30I+xjzCLgZoO7eXCuNV9Lu4zTNWIap6jPKOu8QEXWweUza\nhmn4GyKmrT+1mLhXMqh4U7B2GZdVo9/iY/xcHlVp7UhfOqx1K0OetPn/x+entBR5\nH1uBXU1Yx7tSZ/RN192Af6czMw+THXBh0LgzzJgBIIKdjyy5acLBfh7bnV6PV6G+\nnWWyr4WVrrH4wH3pKisCnIoPpsjEXPSJRnu4PTVELM71l8hZlES9dazRPiMOaxOj\nTfaz1vGa1mDPMbobiN5NH0ueX4LAUDMkpWFuAP+AJ9UqAax+Cq0KX+dUMXqyWY82\nV7jPmgHqYTNRw/zvfdOP1qeqhkIeTp8vPbp3lw==\n-----END CERTIFICATE-----\n"
},
"type": "foursquare-clouderamanager-datasource",
"url": "https://127.0.0.1:7183"
}
带有变量的示例调试输出:
"body": "{\n\"name\": \"Cloudera Manager\",\n\"type\": \"foursquare-clouderamanager-datasource\",\n\"url\":\"https://127.0.0.1:7183\",\n\"access\":\"proxy\",\n\"isDefault\":false,\n\"basicauth\":true,\n\"basicAuthUser\":\"user\",\n\"basicAuthPassword\":\"pass\",\n\"jsonData\": {\n\"cmAPIVersion\":\"v4-5\",\n\"tlsAuthWithCACert\": true},\n\"secureJsonData\":{\n \"tlsCACert\": \"-----BEGIN CERTIFICATE-----\nMIIEmDCCAwCgAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJVUzEL\nMAkGA1UECAwCQ0ExQTA/BgNVBAMMOFNDTSBMb2NhbCBDQSBvbiBkZXBsb3ltZW50\nIGFicnluZHphLWRldi1kZXZsaWdodC1tYW5hZ2VyMB4XDTE5MTExNDA4NDYxOFoX\nDTQ5MTEwMTIzNTk1OVowXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMUEwPwYD\nVQQDDDhTQ00gTG9jYWwgQ0Egb24gZGVwbG95bWVudCBhYnJ5bmR6YS1kZXYtZGV2\nbGlnaHQtbWFuYWdlcjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAK5z\nQOfwxFUMbtMGsVNsheJRNx+8en7iyv4emUu2h7VBIwInzqd9qG3gpTjTHPmp/q/T\nnCi9peKT3EbhvCdbzUmyDX8oAHEIZ0ww+oVyz6omDcV9hkWWsm/JEOyZdP2/OLyb\nv4gdm03vfiZXN6/Xz8C8XZtpgM+pq9+aFK8bQuKE2M333xKqoWnPDlBeFXYKeDjZ\ndtR6OKmChXVViQdkXvhTaG48coBmIrDOCUwm1SMYmohltNSzpdfSgX3GSwVse3fM\nbnWlV/ITDjCkklBcJENn86M7Cb8z55gvwqAHD8Xoqmjt/rzS7hQDcUsG0Zy2cOkl\nuq6ClYpn3Gpm4nXU3bYEvpmiYMKo62wgUz2OC0IAWz4WGvoh0maCKtFnErvGkxkR\nS30Ayz5bPPud3m24gnW92uNcJRStVMrlmg/MdpBr+AiuWrImMX2d1kXBd2zh4L78\n1nk5ZCMyaO6kvnTez6cGc8YqJdFIy76Phw2qeEBhjPkA7+w/BVHSIs2eP79wIwID\nAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRmmdoZo1DrE6uSw1GT\n01061RzynTAfBgNVHSMEGDAWgBRmmdoZo1DrE6uSw1GT01061RzynTAOBgNVHQ8B\nAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggGBAHykOktg6mWPwAXh5RyCKLv+2bVQ\nrtAy4JkTiAsroURm+sdYqQ7KD61vfFI7V1twytOmohfbtJ/4qhcGrh1w1s7yv/a0\nbm7fcG7qViX3QoMaVrgs1wkUQC2JNcT9vPFjHcKA/YtvHVcoYYTPVvr+jS6sbh9e\nvTMu14klVyaqRlPsF30I+xjzCLgZoO7eXCuNV9Lu4zTNWIap6jPKOu8QEXWweUza\nhmn4GyKmrT+1mLhXMqh4U7B2GZdVo9/iY/xcHlVp7UhfOqx1K0OetPn/x+entBR5\nH1uBXU1Yx7tSZ/RN192Af6czMw+THXBh0LgzzJgBIIKdjyy5acLBfh7bnV6PV6G+\nnWWyr4WVrrH4wH3pKisCnIoPpsjEXPSJRnu4PTVELM71l8hZlES9dazRPiMOaxOj\nTfaz1vGa1mDPMbobiN5NH0ueX4LAUDMkpWFuAP+AJ9UqAax+Cq0KX+dUMXqyWY82\nV7jPmgHqYTNRw/zvfdOP1qeqhkIeTp8vPbp3lw==\n-----END CERTIFICATE-----\n\"\n},\n\"database\": \"foursquare-clouderamanager-datasource\"}"
我想也许我在这个字符串中有问题, 但我不知道如何解决这个问题 "tlsCACert": "{{ cert['content'] | b64decode | string }}"
解决方案
问题是您正在使用字符串模板来编写结构化文档(在本例中为 JSON);jinja2 不知道它是 JSON,只知道它是文本。如果您尝试{"hello": "{{ world | string }}"
使用变量 of 进行模板化,您将收到类似的错误,world="abc\ndef"
因为\n
字符串中的 字面意思是插入到胡须中,但 JSON 不允许字符串文字中的换行符。
您有两条前进的道路:要么确保渲染是 JSON 安全的,| to_json
而不是| string
,或者将其组合body
为实际的dict
,以便uri:
正确序列化它
我怀疑这是正在发生的事情,但我以同样的方式确认了这一点:{"body": "{\n\"name\": \"Cloudera Mana...
通过回显该字符串jq -r .body
(或者python -c "import sys, json;print(json.load(sys.stdin)['body'])"
如果您没有jq
方便的话),您会看到其中tlsCACert
有换行符
推荐阅读
- python - discord bot Yaml 文件不会在 python 文件中读取。使用heroku
- javascript - Chrome/Chromium 在不关闭站点的情况下杀死站点的 Javascript || 查看导致无限 javascript 循环的原因
- r - 删除 R 列表中具有特定模式的元素
- python - 使用 MapReduce 查找单词的最大长度
- python - 计算在组中排成一行的值?
- c# - 用 C#9 和 c#10 编写属性的最简单和最简洁的形式
- angular - 有没有办法让父组件被跳过?
- google-chrome - 使用 apt-cache madison 获取稳定的 chrome 版本/包
- python - 如何将表单中的用户输入打印到网站屏幕上
- r - 仅从向量列表中获取最常出现的值