0

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": {}
  }    
}
3
  • Do I understand you correctly, you want to get ['host1', 'host2', 'host3', 'host4']? Commented Dec 13, 2017 at 13:00
  • 2
    What's the actual output you're after like? You're passing an iterable of strings to dict(), which expects an iterable of iterables of length 2. Also, this seems like an XY problem. Commented Dec 13, 2017 at 13:06
  • I've updated the question with the expected output I am trying to achieve. Commented Dec 13, 2017 at 14:54

1 Answer 1

1

It's may help you.

import json
both = {}
start = '['
end = ']'
with open(filename, "r") as f:
    line = f.readline().strip()
    while line:
        if start in line or end in line:
           line = line.split(start)[1].split(end)[0]
        both[line] = line
        line = f.readline().strip()
json_dict = {'all': [both]}

print(json.dumps(json_dict))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.