Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the connection plugin optional and add the option to filter domains / uuids using regex. #101

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 63 additions & 6 deletions plugins/inventory/libvirt.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
uri:
description: Libvirt Connection URI
required: True
type: str
type: string
inventory_hostname:
description: |
What to register as the inventory hostname.
Expand All @@ -35,6 +35,16 @@
- name
- uuid
default: "name"
use_connection_plugin:
description: Whether or not to use the connection plugin.
type: boolean
default: True
filter:
description: |
Use a regex string filter out specific domains (by name or uuid;
this depends on inventory_hostname).
type: string
default: ".*"
requirements:
- "libvirt-python"
'''
Expand All @@ -49,6 +59,8 @@
uri: 'qemu:///system'
'''

import re

from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.errors import AnsibleError
from ansible.module_utils.six import raise_from
Expand Down Expand Up @@ -92,12 +104,26 @@ def parse(self, inventory, loader, path, cache=True):

# TODO(daveol)
# make using connection plugins optional
connection_plugin = dict({
'LXC': 'community.libvirt.libvirt_lxc',
'QEMU': 'community.libvirt.libvirt_qemu'
}).get(connection.getType())
use_connection_plugin = self.get_option('use_connection_plugin')

if use_connection_plugin:
connection_plugin = dict({
'LXC': 'community.libvirt.libvirt_lxc',
'QEMU': 'community.libvirt.libvirt_qemu'
}).get(connection.getType())

# Set the domain filter.
_filter = self.get_option('filter')

for server in connection.listAllDomains():
if not dict({
'uuid': re.match(_filter, server.UUIDString()),
'name': re.match(_filter, server.name())
}).get(
self.get_option('inventory_hostname')
):
continue

inventory_hostname = dict({
'uuid': server.UUIDString(),
'name': server.name()
Expand All @@ -118,7 +144,32 @@ def parse(self, inventory, loader, path, cache=True):
self.inventory.add_group(inventory_hostname_alias)
self.inventory.add_child(inventory_hostname_alias, inventory_hostname)

if connection_plugin is not None:
# Set the interface information.
ifaces = {}

for iface, iface_info in (connection.lookupByName(server.name())).interfaceAddresses(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a lot of work to go through to throw away if the connection plugin is going to be used. Are we doing this so that we add the interface information to the inventory, whether we use the connection plugin or not?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was my intention to have the interface information available in both cases: connection plugin on or off.I can leave it out in case that's a bit overhead. But I can imagine that in some cases you would like to know this kind of information (if someone would like to make modifications within libvirt itself for example).

Another option is to leave it out when the connection plugin is on and add it later on back, together with all the other information that's available from libvirt about a host; so you have a full set of information about each host from libvirt. For example: CPU info, RAM info, DISK info, etc.

I'm fine with any of these options. Or if you have a better one, please let me know!

libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE).items():
# Set interface hw address.
ifaces[iface] = {
'hwaddr': iface_info['hwaddr'],
'addrs': []
}

if 'addrs' in iface_info:

# Append the addresses information to the interface dict.
ifaces[iface]['addrs'] = iface_info['addrs']

# Set the ansible_host variable to the first IP address found.
if not use_connection_plugin and len(iface_info['addrs']) >= 1 and \
'ansible_host' not in self.inventory.hosts[inventory_hostname].get_vars():
self.inventory.set_variable(
inventory_hostname,
'ansible_host',
iface_info['addrs'][0]['addr']
)

if use_connection_plugin and connection_plugin is not None:
self.inventory.set_variable(
inventory_hostname,
'ansible_libvirt_uri',
Expand All @@ -130,6 +181,12 @@ def parse(self, inventory, loader, path, cache=True):
connection_plugin
)

self.inventory.set_variable(
inventory_hostname,
'ansible_libvirt_ifaces',
ifaces
)

# Get variables for compose
variables = self.inventory.hosts[inventory_hostname].get_vars()

Expand Down