I am currently trying to write something to convert an Ansible inventory file into a JSON array which would allow it to be pulled into awx/tower however I have struggled to build a brand new array from the current inventory file format. I am avoiding use of any of the Ansible python API modules as there is no guarantee that future updates won't break these. One solution I found no longer works as there appears to be a change to the Ansible InventoryParser python module so I'm trying to come up with a Python 2.7 solution.
Example inventory file;
[test]
host1
host2
[test1]
host3
host4
The [] signify groups and the other entries are the hosts which will be the key:value relationship. I have converted this to a list in python and I am then attempting to format this into a key:value setup using the [] as where to split the key from the values.
both = []
f = open(filename, "r")
line = f.readline().strip()
while line:
both.append(line)
line = f.readline().strip()
f.close()
start = '['
end = ']'
json_dict = {'all': [dict(item.split(start)[1].split(end)[0] for item in
both)]}
print json.dumps(json_dict)
Unfortunately this returns the error: ValueError: dictionary update sequence element #0 has length 4; 2 is required
Although truth be told I'm not sure this will return what I am looking for regardless.
Hoping someone can point me in the right direction or highlight where I've gone wrong so far.
Cheers
EDIT: Adding some code for what output is actually expected;
{
[test]: {
'hosts': ['host1', 'host2'],
},
[test1]: {
'hosts': ['host3', 'host4'],
}
}
A more detailed output example of what I'm trying to achieve;
{
"databases" : {
"hosts" : [ "host1.example.com", "host2.example.com" ],
"vars" : {
"a" : true
}
},
"webservers" : [ "host2.example.com", "host3.example.com" ],
"atlanta" : {
"hosts" : [ "host1.example.com", "host4.example.com",
"host5.example.com" ],
"vars" : {
"b" : false
},
},
"marietta" : [ "host6.example.com" ],
"5points" : [ "host7.example.com" ]
}
So we have a key which holds the group names and within that there are key:value pairs for hosts and vars.
After some more study I am closer to the output I desire with the following code;
both = {}
group = None
with open(filename, "r") as f:
line = f.readline().strip()
while line:
if line.startswith('#') or line.startswith(';') or len(line) == 0:
continue
if line.startswith("["):
# is a group
group = line
both[group] = {}
elif not line.startswith("["):
host = line
both[group][host] = {}
line = f.readline().strip()
f.close()
return both
Which returns the following which isn't quite what I'm after but I feel like I am making progress;
{
"[test2]": {
"host1": {},
"host2": {}
},
"[test3]": {
"host3": {}
},
"[test]": {
"host4": {},
"host5": {}
}
}
['host1', 'host2', 'host3', 'host4']?dict(), which expects an iterable of iterables of length 2. Also, this seems like an XY problem.