如何在Ansible/Jinja中移除列表字典name字段的firewall__rule_前缀?
Ansible扁平变量转嵌套结构并去除前缀
问题场景
现有Ansible主机变量如下:
firewall__rule_02loopback: | -A INPUT -i lo -j ACCEPT -A OUTPUT -o lo -j ACCEPT firewall__rule_03icmp: | -A INPUT -p icmp -j ACCEPT -A FORWARD -p icmp -j ACCEPT firewall__rule_53dns: ~
需要将其转换为如下嵌套结构:
firewall__rules: - name: 02loopback content: | -A INPUT -i lo -j ACCEPT -A OUTPUT -o lo -j ACCEPT - name: 03icmp content: | -A INPUT -p icmp -j ACCEPT -A FORWARD -p icmp -j ACCEPT - name: 53dns content: None
当前已通过以下代码提取变量,但name字段仍保留firewall__rule_前缀:
set_fact: firewall__rules: '{{ hostvars[inventory_hostname] | dict2items("name", "content") | selectattr("name", "search", "^firewall__rule") }}'
解决方案
修改set_fact逻辑,通过正则替换结合映射处理每个字典的name字段,去掉前缀:
set_fact: firewall__rules: '{{ hostvars[inventory_hostname] | dict2items(key_name="name", value_name="content") | selectattr("name", "search", "^firewall__rule_") | map(lambda item: item | combine({"name": item.name | regex_replace("^firewall__rule_", "")})) | list }}'
逻辑说明
- dict2items:将扁平的键值对变量转换为包含
name(原变量名)和content(原变量值)的字典列表 - selectattr:筛选出变量名以
firewall__rule_开头的项 - map + lambda + combine:遍历每个字典项,用
regex_replace把name字段中的firewall__rule_前缀替换为空,再通过combine生成新字典(避免修改原数据) - list:将map返回的迭代器转换为列表,确保结果格式符合预期
执行后即可得到目标嵌套结构,name字段仅保留规则标识部分。
内容的提问来源于stack exchange,提问作者verideskstar
相关产品推荐
相关产品推荐

