我有一个烦人的字典
ports:
webui: 7200
webadmin: 7209
core_api: 7201
stock_api: 7204
import_export: 7207
我想转换其中的所有键,例如
ports:
staging-webui: 7200
staging-webadmin: 7209
staging-core_api: 7201
staging-stock_api: 7204
staging-import_export: 7207
我在“ vars”部分这样做,所以我不能将“ set_fact”和“ with_items”一起使用来迭代字典。只能通过过滤器吗?
我找到了可行的答案,
env: staging # comes from outside
regex_env: "\"key\": \"{{ env }}-\\1\""
app_upstreams: "{{ ports | dict2items | map('to_json') | map('regex_replace', '\"key\":\\s\"(.*)\"', lookup('vars', 'regex_env')) | map('from_json') }}"
但它看起来确实很丑,还有其他好看的解决方案吗?
答案 0 :(得分:1)
我只是想为自己解决这个问题。我想出了一个不需要使用过滤器插件或 jinja 模板的解决方案。只是纯粹的 ansible playbook 任务。我是在最新版本的 Ansible 上执行此操作的,因此我无法确认它是否适用于旧版本。
它的工作原理是创建具有重命名键的第二个字典,然后用重命名的字典覆盖原始字典。这是一个完整的剧本,您可以将其用作概念证明。
---
- hosts: localhost
connection: local
vars:
prefix: staging
ports:
webui: 7200
webadmin: 7209
core_api: 7201
stock_api: 7204
import_export: 7207
renamed_ports: {}
tasks:
- name: set renamed ports
ansible.builtin.set_fact:
renamed_ports: "{{ renamed_ports | combine({ prefix + '-' + item.key: item.value }) }}"
with_dict: "{{ ports }}"
- name: rewrite original ports
ansible.builtin.set_fact:
ports: "{{ renamed_ports }}"
- name: erase renamed ports if you want to
ansible.builtin.set_fact:
renamed_ports:
- name: print ports
ansible.builtin.debug:
var: ports
...
这是打印端口任务的输出:
TASK [print ports] ****************************************************************************
ok: [localhost] => {
"ports": {
"staging-core_api": 7201,
"staging-import_export": 7207,
"staging-stock_api": 7204,
"staging-webadmin": 7209,
"staging-webui": 7200
}
}
答案 1 :(得分:0)
您可以使用jinja2模板模块来实现此目的,并使用所有变量创建一个yml文件。
剧本->
---
- hosts: localhost
vars:
ports:
webui: 7200
webadmin: 7209
core_api: 7201
stock_api: 7204
import_export: 7207
tasks:
- name: debug module
debug:
var: "{{ item }}"
with_items:
- ports
- name: template
template:
src: templates/template.yml
dest: templates/dest.yml
jinja2模板->
ports:
{% for key, value in ports.iteritems() %}
staging-{{ key }}: {{ value }}
{% endfor %}
输出->
ports:
staging-core_api: 7201
staging-import_export: 7207
staging-stock_api: 7204
staging-webui: 7200
staging-webadmin: 7209
答案 2 :(得分:0)
使用简单的过滤器
$ cat filter_plugins/dict_utils.py
def prefix_key(d, prefix='prefix'):
for key in d.keys():
d[prefix + key] = d.pop(key)
return d
class FilterModule(object):
''' utility filters for operating on dictionary '''
def filters(self):
return {
'prefix_key' : prefix_key
}
下面的任务
- debug:
var: staging_ports
vars:
staging_ports: "{{ ports|prefix_key(prefix='staging_') }}"
给予:
"staging_ports": {
"staging_core_api": 7201,
"staging_import_export": 7207,
"staging_stock_api": 7204,
"staging_webadmin": 7209,
"staging_webui": 7200
}