Ansible根据字符串列表进行拆分,输入为一个列表
我正在努力寻找一种更好的方法,在Ansible中从域名列表中提取出多个带完整限定域名(FQDN)的域名。我需要把域名和未限定名拆分成一个字典。
input_fqdns:
- 'host1.mydomain.internal'
- 'host2.mydomain.net'
known_domains:
- 'mydomain.internal'
- 'mydomain.net'
desired_output:
- unqualified: 'host1'
domain_name: 'mydomain.internal'
- unqualified: 'host2'
domain_name: 'mydomain.net'
我似乎找不到一种方法,能够在一组分隔符上进行拆分。
解决方案
- 最简单的选项是用点来分割名称
- name: Split by dots.
vars:
_split: "{{ input_fqdns | map('split', '.', 1) }}"
_output: "{{ _split | map('zip', ['unqualified', 'domain_name'])
| map('map', 'reverse')
| map('community.general.dict') }}"
debug:
msg: |
desired_output:
{{ _output | to_yaml(indent=2) | indent(2) }}
你将得到所需的输出
msg: |-
desired_output:
- {domain_name: mydomain.internal, unqualified: host1}
- {domain_name: mydomain.net, unqualified: host2}
SEE: The filter community.general.dict
- 但是,如果你想把名字
based on a list of strings拆分开来,请使用过滤器 regex_replace。例如,
- name: Split by regex.
vars:
_regex1: "\\.({{ known_domains | join('|') }})"
_unqualified: "{{ input_fqdns | map('regex_replace', _regex1, '') }}"
_regex2: "^.*({{ known_domains | join('|') }})"
_replace2: '\1'
_domain_name: "{{ input_fqdns | map('regex_replace', _regex2, _replace2) }}"
_output: "{{ _unqualified | zip(_domain_name)
| map('zip', ['unqualified', 'domain_name'])
| map('map', 'reverse')
| map('community.general.dict') }}"
debug:
msg: |
_unqualified:
{{ _unqualified | to_yaml(indent=2) | indent(2) }}
_domain_name:
{{ _domain_name | to_yaml(indent=2) | indent(2) }}
desired_output:
{{ _output | to_yaml(indent=2) | indent(2) }}
也会得到所需的输出
msg: |-
_unqualified:
[host1, host2]
_domain_name:
[mydomain.internal, mydomain.net]
desired_output:
- {domain_name: mydomain.internal, unqualified: host1}
- {domain_name: mydomain.net, unqualified: host2}
备选方案1
我最终创建了一个 自定义过滤插件:
#!/usr/bin/python3
class FilterModule(object):
def filters(self):
return {
'split_multi_contains': self.split_multi_contains
}
def split_multi_contains( self, inputList, needleList, delimiter = ' ', delimiter_limit = -1 ):
result = []
for inputItem in inputList :
splitFound=False
for needleItem in needleList :
if needleItem in inputItem :
result.append(inputItem.split(delimiter,delimiter_limit))
splitFound=True
if splitFound == False :
result.append(inputItem)
return result
备选方案2
另外需要强调的是,已经有一个可用的 [Community] 过滤器,用来实现 get_registrable_domain。一个最小示例的playbook
---
- hosts: localhost
become: false
gather_facts: false
vars:
input_fqdns:
- 'host1.mydomain.internal'
- 'host2.mydomain.net'
tasks:
- name: Split FQDNs
debug:
msg: "{{ item | community.dns.get_registrable_domain }}"
loop: "{{ input_fqdns }}"
将输出以下结果
TASK [Split FQDNs] *********************************
ok: [localhost] => (item=host1.mydomain.internal) =>
msg: mydomain.internal
ok: [localhost] => (item=host2.mydomain.net) =>
msg: mydomain.net
或通过附加 map 过滤器 使之更简化
- name: Split FQDNs
debug:
msg: "{{ input_fqdns | map('community.dns.get_registrable_domain') }}"
得到以下结果
TASK [Split FQDNs] *********************************
ok: [localhost] =>
msg:
- mydomain.internal
- mydomain.net
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。