[第一次提问者。我认为,我已将其定位为一个Ansible问题。如果没有,欢迎进行轻度重定向!]
给出:
gid: 80
ports: [80, 443]
其中端口的数量可能从0到很多
我想产生一个这样的字符串:
“ gid:80:tcp:80,gid:80:tcp:443”
(恰好是FreeBSD mac_portacl规则字符串)
我得到的最远的是:
portacl_rules: "{{ ports | zip_longest([], fillvalue='80') | list }}"
哪个给了我这样的东西
"msg": [
[
80,
"80"
],
[
443,
"80"
]
]
但是:
我可以通过定义一个临时变量来创建gid字符串gid:80
:
gid: 80
_tmp_gid: "gid:{{ gid }}"
但是由于无法将字符串内插到fillvalue中,所以我陷入了困境。
我在format
过滤器周围胡闹,但它似乎将输出字符串作为输入,并将值作为参数,这与我的情况相反。
有什么建议吗?
答案 0 :(得分:0)
如果您不介意一对set_fact
任务,可以这样做:
- set_fact:
rules_list: "{{ rules_list|default([]) + ['gid:{}:tcp:{}'.format(gid, item)] }}"
loop: "{{ ports }}"
- set_fact:
rules_str_1: "{{ ','.join(rules_list) }}"
- debug:
var: rules_str_1
第一个任务创建以下形式的列表:
[
"gid:80:tcp:80",
"gid:80:tcp:443"
]
第二个任务使用,
连接这些项目。
您可以使用涉及regex_replace
过滤器的较毛茸茸的表达式在单个操作中完成此操作:
- set_fact:
rules_str_2: '{{ ",".join(ports|map("regex_replace", "^(.*)$", "gid:{}:tcp:\1".format(gid))) }}'
- debug:
var: rules_str_2
要使此set_fact
任务按编写的方式工作,您必须在外部使用单引号(这禁止使用\
作为转义符)。您可以交换引号,但随后需要写\\
而不是\
。回忆匹配表达式中的(...)
创建了一个捕获组,替换字符串中的\1
扩展为第一个捕获组的值。
将所有内容放到一本剧本中
---
- hosts: localhost
gather_facts: false
vars:
gid: 80
ports: [80, 443]
tasks:
- set_fact:
rules_list: "{{ rules_list|default([]) + ['gid:{}:tcp:{}'.format(gid, item)] }}"
loop: "{{ ports }}"
- set_fact:
rules_str_1: "{{ ','.join(rules_list) }}"
- debug:
var: rules_str_1
- set_fact:
rules_str_2: '{{ ",".join(ports|map("regex_replace", "(.*)", "gid:{}:tcp:\1".format(gid))) }}'
- debug:
var: rules_str_2
这将产生以下输出:
PLAY [localhost] ******************************************************************************************************************************************************************************
TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=80)
ok: [localhost] => (item=443)
TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"rules_str_1": "gid:80:tcp:80,gid:80:tcp:443"
}
TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"rules_str_2": "gid:80:tcp:80,gid:80:tcp:443"
}
PLAY RECAP ************************************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0