我通过http.get检索ansible主机文件,如下所示:
[group1]
host1
host2
[group2]
host3
host4
如何从每个组开始迭代,然后折叠以下行,直到下一个组成为这样的嵌套哈希?
{ "group1" => ["host1", "1host2"], "group2" => ["host3", "host4"] }
答案 0 :(得分:2)
如果您不想进行完整解析,可以将语料库视为包含节的INI文件。这样的文件可能很棘手并且有许多边缘情况,特别是如果您不能严格定义部分的分隔方式。但是,以下内容适用于您的特定语料库。
# Read the file.
ini = File.read '/tmp/example.ini'
# Split the file into sections. Assumes only one blank line between
# sections.
sections = ini.scan /^\[.*?(?:\n\n|\z)/m
# Return an array of hashes, then merge them. Use the first element
# from each split as the hash key.
hash = sections.map do |section|
array = section.split
key = array.shift.delete '[]'
{ key => array }
end.reduce({}, :merge)
#=> {"group1"=>["host1", "host2"], "group2"=>["host3", "host4"]}
在更复杂的类似INI的文件中,有多种方法可能会失败,因此如果你走这条路,你可能需要对文件进行更全面的解析。或者,您可以将结果保存为文件,然后parse the inventory into a Ruby hash using the Ansible CLI。
答案 1 :(得分:1)
您可以将Ansible inventory的输出解析为(主要)JSON。这实际上比直接解析类似INI的文件更容易,更可靠,尽管Ansible CLI将您想要的结果包装在顶级groups
值中。
require 'json'
output = %x(ansible localhost -i /tmp/example.ini -m debug -a 'var=groups')
json = JSON.parse(output.sub /^.*=>/, '')
json['groups']
#=> {"all"=>["host1", "host2", "host3", "host4"], "group1"=>["host1", "host2"], "group2"=>["host3", "host4"], "ungrouped"=>["localhost"]}
json['groups']['group1']
#=> ["host1", "host2"]
# Use Hash#dig on recent Rubies to simplify lookups.
json.dig 'groups', 'group2'
#=> ["host3", "host4"]
如果确实只需要以字符串group
开头的组,则可以动态提取它们。例如:
json['groups'].keys.select { |k| k.start_with? 'group' }.map do |key|
{ key => json['groups'][key] }
end.reduce({}, :merge)
#=> {"group1"=>["host1", "host2"], "group2"=>["host3", "host4"]}
答案 2 :(得分:1)
有一个ansible-inventory
命令。
ansible-inventory -i path/to/inventory --export --list
示例结果就像
{
"all": {
"children": [
"db",
"ungrouped",
"web"
]
},
"db": {
"hosts": [
"demo_db"
]
},
"web": {
"hosts": [
"demo_app"
]
}
}