1#!/usr/bin/env python
2
3# (c) 2013, Michael Scherer <misc@zarb.org>
4# (c) 2014, Hiroaki Nakamura <hnakamur@gmail.com>
5# (c) 2016, Andew Clarke <andrew@oscailte.org>
6#
7# This file is based on https://github.com/ansible/ansible/blob/devel/plugins/inventory/libvirt_lxc.py which is part of Ansible,
8# and https://github.com/hnakamur/lxc-ansible-playbooks/blob/master/provisioning/inventory-lxc.py
9#
10# NOTE, this file has some obvious limitations, improvements welcome
11#
12# Ansible is free software: you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation, either version 3 of the License, or
15# (at your option) any later version.
16#
17# Ansible is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
24
25import os
26from subprocess import Popen, PIPE
27import distutils.spawn
28import sys
29import json
30
31from ansible.module_utils.six.moves import configparser
32
33# Set up defaults
34resource = 'local:'
35group = 'lxd'
36connection = 'lxd'
37hosts = {}
38result = {}
39
40# Read the settings from the lxd.ini file
41config = configparser.SafeConfigParser()
42config.read(os.path.dirname(os.path.realpath(__file__)) + '/lxd.ini')
43if config.has_option('lxd', 'resource'):
44    resource = config.get('lxd', 'resource')
45if config.has_option('lxd', 'group'):
46    group = config.get('lxd', 'group')
47if config.has_option('lxd', 'connection'):
48    connection = config.get('lxd', 'connection')
49
50# Ensure executable exists
51if distutils.spawn.find_executable('lxc'):
52
53    # Set up containers result and hosts array
54    result[group] = {}
55    result[group]['hosts'] = []
56
57    # Run the command and load json result
58    pipe = Popen(['lxc', 'list', resource, '--format', 'json'], stdout=PIPE, universal_newlines=True)
59    lxdjson = json.load(pipe.stdout)
60
61    # Iterate the json lxd output
62    for item in lxdjson:
63
64        # Check state and network
65        if 'state' in item and item['state'] is not None and 'network' in item['state']:
66            network = item['state']['network']
67
68            # Check for eth0 and addresses
69            if 'eth0' in network and 'addresses' in network['eth0']:
70                addresses = network['eth0']['addresses']
71
72                # Iterate addresses
73                for address in addresses:
74
75                    # Only return inet family addresses
76                    if 'family' in address and address['family'] == 'inet':
77                        if 'address' in address:
78                            ip = address['address']
79                            name = item['name']
80
81                            # Add the host to the results and the host array
82                            result[group]['hosts'].append(name)
83                            hosts[name] = ip
84
85    # Set the other containers result values
86    result[group]['vars'] = {}
87    result[group]['vars']['ansible_connection'] = connection
88
89# Process arguments
90if len(sys.argv) == 2 and sys.argv[1] == '--list':
91    print(json.dumps(result))
92elif len(sys.argv) == 3 and sys.argv[1] == '--host':
93    if sys.argv[2] == 'localhost':
94        print(json.dumps({'ansible_connection': 'local'}))
95    else:
96        if connection == 'lxd':
97            print(json.dumps({'ansible_connection': connection}))
98        else:
99            print(json.dumps({'ansible_connection': connection, 'ansible_host': hosts[sys.argv[2]]}))
100else:
101    print("Need an argument, either --list or --host <host>")
102