我一直在努力解决我认为简单的问题,但无法根据变量更新yaml文件
我有什么:
YAML格式的ansible主机文件。此主机文件始终不是100%相同。它可以有一个多个图像值的字典(作为一个例子),我只想要改变一个。
namespace: demo1
images:
image1:
path: "path1"
version: "v1"
image2:
path: "path2"
version: "1.2.3"
user: "root"
一个YAML文件,其中包含我要替换的内容的键/值。我们已经在这个YAML中为系统的其他部分配置了很多配置,所以如果我能帮助它(ini,JSON等),我不想分离到其他类型的配置类型我真的想要这是点符号。
schema: v1.0
hostfile:
- path: path/to/ansible_hosts_file
images:
image1.version: v1.1
我试图找到一种方法从#1加载YAML,读取密钥hostfile.images。[variable]来替换并用新值写回原始的ansible文件。我一直在变量方面绊倒,因为今天它可以是image1.version,下一个配置它的image2.path或两者同时。
答案 0 :(得分:0)
我认为您的问题主要来自将键值对与点分表示法混合。即。
images:
image1.version: v1.1
而不是
images.image1.version: v1.1
已经为Python和任意分隔符(不一定是'。')in this answer解析了点分表示法。设置只涉及提供两个额外的函数,这些函数采用第二个参数,这是设置并将它们移植到CommentedMap
resp上的值。 CommentesSeq
)
根据您需要根据您的密钥进行预选:
upd = ruamel.yaml.round_trip_load(open('update.yaml')
# schema check here
for hostfile in upd['hostfile']:
data = ruamel.yaml.round_trip_load(open(hostfile['path']))
images = data['images']
for dotted in hostfile['images']:
val = hostfile['images'][dotted]
images.string_set(dotted, val)
实际的string_set
- 代码看起来像(未经测试):
def mapping_string_set(self, s, val, delimiter=None, key_delim=None):
def p(v):
try:
v = int(v)
except:
pass
return v
# possible extend for primitives like float, datetime, booleans, etc.
if delimiter is None:
delimiter = '.'
if key_delim is None:
key_delim = ','
try:
key, rest = s.split(delimiter, 1)
except ValueError:
key, rest = s, None
if key_delim in key:
key = tuple((p(key) for key in key.split(key_delim)))
else:
key = p(key)
if rest is None:
self[key] = val
return
self[key].string_set(rest, val, delimiter, key_delim)
ruamel.yaml.comments.CommentedMap.string_set = mapping_string_set
def sequence_string_set(self, s, delimiter=None, key_delim=None):
if delimiter is None:
delimiter = '.'
try:
key, rest = s.split(delimiter, 1)
except ValueError:
key, rest = s, None
key = int(key)
if rest is None:
self[key] = val
return
self[key].string_set(rest, val, delimiter, key_delim)
ruamel.yaml.comments.CommentedSeq.string_set = sequence_string_set