source/projects/kook/bin/kook-inventory

136 lines
3.7 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Usage:
kook-inventory [--list | --host <hostname> | --import <inventory.yml>] [--[no-]synchronization]
Create a Kook client, and use it to generate Ansible formatted JSON inventory.
In keeping with the Ansible inventory protocol, requires --list or --host.
Otherwise this message will be printed.
"""
import argparse
import json
import sys
from kook.client import KookClient
import yaml
def merge(m1, m2):
return {**m1, **m2}
def get_inventory(client):
inventory = {}
hostvars = {}
inventory["_meta"] = {"hostvars": hostvars}
# Import hosts
for host in client.hosts():
hostvars[host.name] = host.canonicalized_vars(meta=False)
for group in client.groups():
inventory[group.name] = {"children": [], "hosts": [], "vars": {}}
inventory[group.name]["children"].extend([g.name for g in group.children()])
inventory[group.name]["hosts"].extend([h.name for h in group.hosts()])
return inventory
def get_host(client, hostname):
host = client.host(hostname)
if host:
return host.canonicalized_vars()
def import_inventory(client, filename):
with open(filename, "r") as _f:
data = yaml.safe_load(_f)
# mapcat out all the group(s)
groups = list(data.items())
for groupname, groupdata in groups:
groups.extend((groupdata or {}).get("children", {}).items())
# Import all the group(s)
for groupname, groupdata in groups:
g = client.create_group(groupname)
print("Created,", g)
if groupdata is None:
continue
# Import the vars
for var, val in groupdata.get("vars", {}).items():
# Fixup my key(s)
if var == "ansible_host":
var = "host_address"
g.set_var(var, val)
# Import the direct host bindings
for hostname, hostvars in groupdata.get("hosts", {}).items():
h = client.create_host(hostname)
h.add_group(g)
print(g, "added host", h)
for var, val in (hostvars or {}).items():
g.set_host_var(hostname, var, val)
# Import the child group(s)
for childname, childvars in groupdata.get("children", {}).items():
child = client.create_group(childname)
child.add_group(g)
# FIXME (arrdem 2019-08-10):
# Support group on child group vars?
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--synchronization",
dest="use_synchronization",
default=True,
action="store_true",
)
parser.add_argument(
"--no-synchronization", dest="use_synchronization", action="store_false"
)
parser.add_argument(
"--list",
action="store_true",
dest="list",
default=False,
help="Output inventory groups and hosts",
)
parser.add_argument(
"--host",
dest="host",
default=None,
metavar="HOST",
help="Output variables only for the given hostname",
)
parser.add_argument(
"--import",
dest="_import",
default=None,
metavar="IMPORT",
help="Import a YAML inventory file",
)
parser.add_argument("-b", "--bootstrap", help="Bootstrap servers list to use")
args = parser.parse_args(sys.argv[1:])
client = KookClient(
hosts=args.bootstrap, use_synchronization=args.use_synchronization
)
if args.host:
print(json.dumps(get_host(client, args.host), indent=2, sort_keys=True))
elif args.list:
print(json.dumps(get_inventory(client), indent=2, sort_keys=True))
elif args._import:
import_inventory(client, args._import)
else:
print(__doc__)