summaryrefslogtreecommitdiffstats
path: root/inventory/libvirt/hosts/libvirt_generic.py
diff options
context:
space:
mode:
Diffstat (limited to 'inventory/libvirt/hosts/libvirt_generic.py')
-rwxr-xr-xinventory/libvirt/hosts/libvirt_generic.py95
1 files changed, 53 insertions, 42 deletions
diff --git a/inventory/libvirt/hosts/libvirt_generic.py b/inventory/libvirt/hosts/libvirt_generic.py
index 4652f112e..1c9c17308 100755
--- a/inventory/libvirt/hosts/libvirt_generic.py
+++ b/inventory/libvirt/hosts/libvirt_generic.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python2
-"""
+'''
libvirt external inventory script
=================================
@@ -12,7 +12,7 @@ To use this, copy this file over /etc/ansible/hosts and chmod +x the file.
This, more or less, allows you to keep one central database containing
info about all of your managed instances.
-"""
+'''
# (c) 2015, Jason DeTiberus <jdetiber@redhat.com>
#
@@ -36,9 +36,7 @@ info about all of your managed instances.
import argparse
import ConfigParser
import os
-import re
import sys
-from time import time
import libvirt
import xml.etree.ElementTree as ET
@@ -49,8 +47,11 @@ except ImportError:
class LibvirtInventory(object):
+ ''' libvirt dynamic inventory '''
def __init__(self):
+ ''' Main execution path '''
+
self.inventory = dict() # A list of groups and the hosts in that group
self.cache = dict() # Details about hosts in the inventory
@@ -59,13 +60,15 @@ class LibvirtInventory(object):
self.parse_cli_args()
if self.args.host:
- print self.json_format_dict(self.get_host_info(), self.args.pretty)
+ print _json_format_dict(self.get_host_info(), self.args.pretty)
elif self.args.list:
- print self.json_format_dict(self.get_inventory(), self.args.pretty)
+ print _json_format_dict(self.get_inventory(), self.args.pretty)
else: # default action with no options
- print self.json_format_dict(self.get_inventory(), self.args.pretty)
+ print _json_format_dict(self.get_inventory(), self.args.pretty)
def read_settings(self):
+ ''' Reads the settings from the libvirt.ini file '''
+
config = ConfigParser.SafeConfigParser()
config.read(
os.path.dirname(os.path.realpath(__file__)) + '/libvirt.ini'
@@ -73,6 +76,8 @@ class LibvirtInventory(object):
self.libvirt_uri = config.get('libvirt', 'uri')
def parse_cli_args(self):
+ ''' Command line argument processing '''
+
parser = argparse.ArgumentParser(
description='Produce an Ansible Inventory file based on libvirt'
)
@@ -96,25 +101,27 @@ class LibvirtInventory(object):
self.args = parser.parse_args()
def get_host_info(self):
+ ''' Get variables about a specific host '''
+
inventory = self.get_inventory()
if self.args.host in inventory['_meta']['hostvars']:
return inventory['_meta']['hostvars'][self.args.host]
def get_inventory(self):
+ ''' Construct the inventory '''
+
inventory = dict(_meta=dict(hostvars=dict()))
conn = libvirt.openReadOnly(self.libvirt_uri)
if conn is None:
- print "Failed to open connection to %s" % libvirt_uri
+ print "Failed to open connection to %s" % self.libvirt_uri
sys.exit(1)
domains = conn.listAllDomains()
if domains is None:
- print "Failed to list domains for connection %s" % libvirt_uri
+ print "Failed to list domains for connection %s" % self.libvirt_uri
sys.exit(1)
- arp_entries = self.parse_arp_entries()
-
for domain in domains:
hostvars = dict(libvirt_name=domain.name(),
libvirt_id=domain.ID(),
@@ -130,21 +137,30 @@ class LibvirtInventory(object):
hostvars['libvirt_status'] = 'running'
root = ET.fromstring(domain.XMLDesc())
- ns = {'ansible': 'https://github.com/ansible/ansible'}
- for tag_elem in root.findall('./metadata/ansible:tags/ansible:tag', ns):
+ ansible_ns = {'ansible': 'https://github.com/ansible/ansible'}
+ for tag_elem in root.findall('./metadata/ansible:tags/ansible:tag', ansible_ns):
tag = tag_elem.text
- self.push(inventory, "tag_%s" % tag, domain_name)
- self.push(hostvars, 'libvirt_tags', tag)
+ _push(inventory, "tag_%s" % tag, domain_name)
+ _push(hostvars, 'libvirt_tags', tag)
# TODO: support more than one network interface, also support
# interface types other than 'network'
interface = root.find("./devices/interface[@type='network']")
if interface is not None:
+ source_elem = interface.find('source')
mac_elem = interface.find('mac')
- if mac_elem is not None:
- mac = mac_elem.get('address')
- if mac in arp_entries:
- ip_address = arp_entries[mac]['ip_address']
+ if source_elem is not None and \
+ mac_elem is not None:
+ # Adding this to disable pylint check specifically
+ # ignoring libvirt-python versions that
+ # do not include DHCPLeases
+ # This is needed until we upgrade the build bot to
+ # RHEL7 (>= 1.2.6 libvirt)
+ # pylint: disable=no-member
+ dhcp_leases = conn.networkLookupByName(source_elem.get('network')) \
+ .DHCPLeases(mac_elem.get('address'))
+ if len(dhcp_leases) > 0:
+ ip_address = dhcp_leases[0]['ipaddr']
hostvars['ansible_ssh_host'] = ip_address
hostvars['libvirt_ip_address'] = ip_address
@@ -152,28 +168,23 @@ class LibvirtInventory(object):
return inventory
- def parse_arp_entries(self):
- arp_entries = dict()
- with open('/proc/net/arp', 'r') as f:
- # throw away the header
- f.readline()
-
- for line in f:
- ip_address, _, _, mac, _, device = line.strip().split()
- arp_entries[mac] = dict(ip_address=ip_address, device=device)
-
- return arp_entries
-
- def push(self, my_dict, key, element):
- if key in my_dict:
- my_dict[key].append(element)
- else:
- my_dict[key] = [element]
-
- def json_format_dict(self, data, pretty=False):
- if pretty:
- return json.dumps(data, sort_keys=True, indent=2)
- else:
- return json.dumps(data)
+def _push(my_dict, key, element):
+ '''
+ Push element to the my_dict[key] list.
+ After having initialized my_dict[key] if it dosn't exist.
+ '''
+
+ if key in my_dict:
+ my_dict[key].append(element)
+ else:
+ my_dict[key] = [element]
+
+def _json_format_dict(data, pretty=False):
+ ''' Serialize data to a JSON formated str '''
+
+ if pretty:
+ return json.dumps(data, sort_keys=True, indent=2)
+ else:
+ return json.dumps(data)
LibvirtInventory()