1#!/usr/local/bin/python3.8
2#
3# (c) 2015-16 Florian Haas, hastexo Professional Services GmbH
4# <florian@hastexo.com>
5# Based in part on:
6# libvirt_lxc.py, (c) 2013, Michael Scherer <misc@zarb.org>
7#
8# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
9
10"""
11Ansible inventory script for LXC containers. Requires Python
12bindings for LXC API.
13
14In LXC, containers can be grouped by setting the lxc.group option,
15which may be found more than once in a container's
16configuration. So, we enumerate all containers, fetch their list
17of groups, and then build the dictionary in the way Ansible expects
18it.
19"""
20
21from __future__ import (absolute_import, division, print_function)
22__metaclass__ = type
23
24import sys
25import lxc
26import json
27
28
29def build_dict():
30    """Returns a dictionary keyed to the defined LXC groups. All
31    containers, including the ones not in any group, are included in the
32    "all" group."""
33    # Enumerate all containers, and list the groups they are in. Also,
34    # implicitly add every container to the 'all' group.
35    containers = dict([(c,
36                        ['all'] +
37                        (lxc.Container(c).get_config_item('lxc.group') or []))
38                       for c in lxc.list_containers()])
39
40    # Extract the groups, flatten the list, and remove duplicates
41    groups = set(sum(containers.values(), []))
42
43    # Create a dictionary for each group (including the 'all' group
44    return dict([(g, {'hosts': [k for k, v in containers.items() if g in v],
45                      'vars': {'ansible_connection': 'lxc'}}) for g in groups])
46
47
48def main(argv):
49    """Returns a JSON dictionary as expected by Ansible"""
50    result = build_dict()
51    if len(argv) == 2 and argv[1] == '--list':
52        json.dump(result, sys.stdout)
53    elif len(argv) == 3 and argv[1] == '--host':
54        json.dump({'ansible_connection': 'lxc'}, sys.stdout)
55    else:
56        print("Need an argument, either --list or --host <host>", file=sys.stderr)
57
58
59if __name__ == '__main__':
60    main(sys.argv)
61