原始列表具有以下结构:
endpoints:
- address: 10.10.10.1
name: hostname1:867
write: yes
- address: 10.10.10.2
name: hostname2:867
write: yes
- address: 10.10.10.3
name: hostname3:867
write: yes
我正在尝试通过拆分“名称”字段来创建新列表,结果如下:
endpoints:
- address: 10.10.10.1
name: hostname1
port: 867
write: yes
- address: 10.10.10.2
name: hostname2
port: 867
write: yes
- address: 10.10.10.3
name: hostname3
port: 867
write: yes
我尝试了json_query和map('regex_replace')的组合,然后设置了一个新事实,但没有成功。
答案 0 :(得分:0)
虽然使用json_query
似乎是合理的选择,但由于JMESPath(构建json_query的项目)缺少split
函数,因此我不确定它的工作方式。
您可以考虑编写自己的过滤器插件。它增加了将来的剧本维护的复杂性,但是以这种方式进行数据操作在python中要容易得多。
在您的剧本目录中,创建一个名为filter_plugins
的文件夹和一个包含内容的文件split_hostname.py
>
#!/usr/bin/env python
class FilterModule(object):
def filters(self):
return {'split_hostname': split_hostname}
def split_hostname(endpoints):
new_endpoints = []
for endpoint in endpoints:
hostname, port = endpoint["name"].split(":")
endpoint["name"] = hostname
endpoint["port"] = port
new_endpoints.append(endpoint)
return new_endpoints
然后在您的剧本中使用过滤器:
- set_fact:
new_endpoints: "{{ endpoints | split_hostname }}"
这是一个非常基本的示例。如果您选择沿着这条路走,则可能需要添加一些错误处理。
答案 1 :(得分:0)
以下任务
- set_fact:
ep2: "{{ ep2|
default([]) + [
{'write': item.write,
'address': item.address,
'port': item.name.split(':').1,
'name': item.name.split(':').0} ]
}}"
loop: "{{ endpoints }}"
- debug:
var: ep2
给予
ep2:
- address: 10.10.10.1
name: hostname1
port: '867'
write: true
- address: 10.10.10.2
name: hostname2
port: '867'
write: true
- address: 10.10.10.3
name: hostname3
port: '867'
write: true
下面的任务更加灵活,仅在定义时添加项目 write 和地址
- set_fact:
ep: "{{ ep|
default([]) + [ {}|
combine((item.write is defined)|
ternary({'write': item.write}, {}))|
combine((item.address is defined)|
ternary({'address': item.address}, {}))|
combine({'port': item.name.split(':').1})|
combine({'name': item.name.split(':').0}) ]
}}"
loop: "{{ endpoints }}"
如果可以使用完整的 item ,则可以简化任务
- set_fact:
ep: "{{ ep|
default([]) + [
item|
combine({'port': item.name.split(':').1})|
combine({'name': item.name.split(':').0}) ]
}}"
loop: "{{ endpoints }}"
如果您想尝试 filter_plugins ,请使用dict_utils。以下是简化的 dict_add_hash 过滤器。
$ cat filter_plugins/dict_utils.py
def dict_add_hash(d, h):
for k, v in h.iteritems():
d[k] = v
return d
class FilterModule(object):
''' Ansible filters. Interface to Python dictionary methods.'''
def filters(self):
return {
'dict_add_hash' : dict_add_hash
}
任务
- set_fact:
ep2: "{{ ep2|
default([]) + [
item|
dict_add_hash({'port': item.name.split(':').1})|
dict_add_hash({'name': item.name.split(':').0}) ]
}}"
loop: "{{ endpoints }}"
- debug:
var: ep2
给出相同的结果
ep2:
- address: 10.10.10.1
name: hostname1
port: '867'
write: true
- address: 10.10.10.2
name: hostname2
port: '867'
write: true
- address: 10.10.10.3
name: hostname3
port: '867'
write: true
查看所有可用的plugins。