ans*_*erp 5 python jinja2 ansible
我们需要将双引号转义的 JSON 字符串提供到 NodeJS 产品的 AWS 密钥中。单内双引号格式不适用于该应用程序。结构化数据采用 dict-list-dict 格式。例子:
{
"data": "[{\"URL\": \"beta.test.net\", \"token\": \"beta-token\"}, {\"URL\": \"beta-prod.test.net\", \"token\": \"beta-prod-token\"}]"
}
Run Code Online (Sandbox Code Playgroud)
我尝试了许多过滤器来让 ansible 和 jinja 获取 JSON 变量并将其转换为所需格式的字符串,但结果从来都不太正确。| 到_json | 字符串给出以下结果:
{
"data": "[{'URL': 'beta.test.net', 'token': 'beta-token'}, {'token': 'test-token', 'URL': 'beta-prod.test.net'}]"
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用替换或正则表达式替换时,即使使用保护字符,我最终也会遇到 python 解析错误。下面是一个示例,仅使用坟墓的重音“`”转义进行替换。
TASK [Update secret in AWS] ***************************************************************************************************
task path: path:27
The full traceback is:
Traceback (most recent call last):
File "/home/.local/lib/python3.5/site-packages/ansible/executor/task_executor.py", line 146, in run
res = self._execute()
File "/home/.local/lib/python3.5/site-packages/ansible/executor/task_executor.py", line 587, in _execute
self._task.post_validate(templar=templar)
File "/home/.local/lib/python3.5/site-packages/ansible/playbook/task.py", line 296, in post_validate
super(Task, self).post_validate(templar)
File "/home/.local/lib/python3.5/site-packages/ansible/playbook/base.py", line 431, in post_validate
value = templar.template(getattr(self, name))
File "/home/.local/lib/python3.5/site-packages/ansible/template/__init__.py", line 623, in template
disable_lookups=disable_lookups,
File "/home/.local/lib/python3.5/site-packages/ansible/template/__init__.py", line 578, in template
disable_lookups=disable_lookups,
File "/home/.local/lib/python3.5/site-packages/ansible/template/__init__.py", line 806, in do_template
data = _escape_backslashes(data, myenv)
File "/home/.local/lib/python3.5/site-packages/ansible/template/__init__.py", line 149, in _escape_backslashes
for token in jinja_env.lex(d2):
File "/home/.local/lib/python3.5/site-packages/jinja2/lexer.py", line 739, in tokeniter
name, filename)
jinja2.exceptions.TemplateSyntaxError: unexpected char '`' at 51
line 1
fatal: [beta-prod]: FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
}
Run Code Online (Sandbox Code Playgroud)
使用正则表达式替换我可以完全删除单引号并将其替换为“\”,但是任何添加“\””的尝试都将始终失败并出现上述解析错误。
以下是调用 AWS 机密的 ansible 代码,以及我提供正确格式的一些尝试:
- name: Update secret in AWS
aws_secret:
name: '{{ aws_secret_name }}'
state: present
secret_type: 'string'
# secret: "{{ token_list_update | to_json | replace(\"'\",\"\") | string }}"
secret: '{{ token_list_update | to_json | string }}'
# secret: ' {"data": "{{ token_list | to_json | regex_replace(`"`,`\\"`) }}"}'
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。我意识到我需要编写自己的过滤器来处理这个问题。我确实询问过应用程序是否接受单双引号 JSON 字符串,但团队表示这是不可接受的。格式必须是双引号转义的 JSON 字符串。
最终编辑:
经过几天的努力,终于解决了这个问题。在每一步中,您都需要转换正确的类型以保留 JSON 格式。进行更新时,每个列表元素都需要过滤为_json。例子:
token_list: "{{ (token_list | default([]) + [_update]) | to_json }}"
Run Code Online (Sandbox Code Playgroud)
_update 是一个辅助变量,它是 JMESPath 搜索
最终提交到AWS:
- name: Update secret in AWS
aws_secret:
name: "{{ aws_secret_name }}"
state: present
secret_type: "string"
secret: "{\"data\":{{ token_list | to_json}}}"
Run Code Online (Sandbox Code Playgroud)
使用本机 jinja2 过滤器:tojson
https://jinja.palletsprojects.com/en/2.10.x/templates/#tojson
我使用它的方式如下:
toto.json.j2:
{"hello" : "world"}
Run Code Online (Sandbox Code Playgroud)
{{ lookup('template', './toto.json.j2') | to_json | tojson }}
Run Code Online (Sandbox Code Playgroud)
这会生成:
"{\"hello\" : \"world\"}"
Run Code Online (Sandbox Code Playgroud)
它有点长,但这应该能满足您的需要。
剧本
---
- hosts: localhost
tasks:
- name: get string
shell: "python3.7 print-string.py"
register: json_string
- name: Update secret in AWS
aws_secret:
name: 'testing/json_string'
state: present
secret_type: 'string'
secret: "{{ json_string['stdout'] | string }}"
Run Code Online (Sandbox Code Playgroud)
打印字符串.py
import json
data = {
"data": "[{'URL': 'beta.test.net', 'token': 'beta-token'}, {'token': 'beta-prod-token', 'URL': 'beta-prod.test.net'}]"
}
print(json.dumps(data).replace('[{\'', '[{\\"').replace('\': \'', '\\": \\"').replace('\'', '\\"'))
Run Code Online (Sandbox Code Playgroud)
将产生:
{
"data": "[{\"URL\": \"beta.test.net\", \"token\": \"beta-token\"}, {\"token\": \"beta-prod-token\", \"URL\": \"beta-prod.test.net\"}]"
}
Run Code Online (Sandbox Code Playgroud)