|
#!/usr/bin/env python |
|
|
|
""" |
|
This is an example script for implementing dynamic inventory in Ansible. |
|
It could have been written in bash, but python is much easier to read. |
|
""" |
|
|
|
import argparse |
|
import json |
|
|
|
# Example hosts store |
|
store = { |
|
"postgres-1": { |
|
"metadatafromstore": { |
|
"ip": ['172.16.1.1'], |
|
'discs': ['/dev/vda', '/dev/sda'], |
|
'users': ['grey'], |
|
'mounts': { |
|
"/": '/dev/vda', |
|
"/opt/postgres/data": "/dev/sda", |
|
}, |
|
} |
|
}, |
|
"apache": { |
|
"metadatafromstore": { |
|
"ip": ['172.16.1.3'], |
|
'discs': ['/dev/vda'], |
|
'mounts': { |
|
"/": '/dev/vda', |
|
}, |
|
} |
|
}, |
|
} |
|
|
|
|
|
def get_host_vars(host): |
|
data = { |
|
'ansible_host': host, |
|
'ansible_user': 'root', |
|
} |
|
if host in store: |
|
metadata = store[host].get('metadatafromstore', {}) or {} |
|
if metadata.get('ip'): |
|
data['ansible_host'] = metadata['ip'][0] |
|
if 'users' in metadata: |
|
data['ansible_user'] = metadata['users'][0] |
|
data.update(metadata) |
|
return data |
|
|
|
|
|
def get_vars(host, pretty=False): |
|
""" |
|
Function which return json data of host's variables. |
|
Required only if hostvars in meta was not set. |
|
""" |
|
return json.dumps({}, indent=pretty) |
|
|
|
|
|
def get_list(pretty=False): |
|
""" |
|
Function which return inventory data for hosts. |
|
Example contains all variants of groups. Syntax as yaml inventory but with '_meta' section. |
|
|
|
- 'hostvars' is all variables for hosts. |
|
- 'all' is default group which should be always created. |
|
- 'ungrouped' is testing group with hosts. |
|
""" |
|
hostvars, ungrouped = {}, [] |
|
|
|
for host in store: |
|
ungrouped.append(host) |
|
hostvars[host] = get_host_vars(host) |
|
|
|
data = { |
|
'_meta': { |
|
'hostvars': hostvars |
|
}, |
|
'all': { |
|
'children': [ |
|
'ungrouped' |
|
] |
|
}, |
|
'ungrouped': { |
|
'hosts': ungrouped |
|
} |
|
} |
|
return json.dumps(data, indent=pretty) |
|
|
|
|
|
# Parse arguments. |
|
# Ansible require two: '--list' and output of all data and '--host [hostname] for getting variables about one host' |
|
parser = argparse.ArgumentParser() |
|
parser.add_argument( |
|
'--pretty', |
|
action='store_true', |
|
default=False, |
|
help="Pretty print JSON" |
|
) |
|
parser.add_argument( |
|
"--list", |
|
action='store', |
|
nargs="*", |
|
default="dummy", |
|
help="Show JSON of all managed hosts" |
|
) |
|
parser.add_argument( |
|
"--host", |
|
action='store', |
|
help="Display vars related to the host" |
|
) |
|
args = parser.parse_args() |
|
|
|
# Print output will be parsed via ansible as inventory (like a file). |
|
if args.host: |
|
print(get_vars(args.host, args.pretty)) |
|
elif len(args.list) >= 0: |
|
print(get_list(args.pretty)) |
|
else: |
|
raise ValueError("Expecting either --host $HOSTNAME or --list") |