wip: dynamic inventory
parent
143c96074e
commit
ae39d2a232
|
@ -4,6 +4,7 @@
|
||||||
inventory = hosts
|
inventory = hosts
|
||||||
|
|
||||||
callback_plugins = plugins/callback
|
callback_plugins = plugins/callback
|
||||||
|
inventory_plugins = plugins/inventory
|
||||||
|
|
||||||
gathering = smart
|
gathering = smart
|
||||||
fact_caching = jsonfile
|
fact_caching = jsonfile
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
import logging
|
||||||
|
from xml.etree import ElementTree as etree
|
||||||
|
|
||||||
|
import libvirt
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
name: pyrocufflink
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- constructed
|
||||||
|
short_description: Pyrocufflink inventory source
|
||||||
|
version_added: ''
|
||||||
|
description:
|
||||||
|
- Dynamic inventory for Pyrocufflink machines
|
||||||
|
author:
|
||||||
|
- Dustin C. Hatch <dustin@hatch.name>
|
||||||
|
options:
|
||||||
|
plugin:
|
||||||
|
description:
|
||||||
|
Token that ensures this is a source file for the 'pyrocufflink' plugin.
|
||||||
|
required: True
|
||||||
|
choices: ['pyrocufflink']
|
||||||
|
'''
|
||||||
|
|
||||||
|
log = logging.getLogger('ansible.plugins.inventory.pyrocufflink')
|
||||||
|
|
||||||
|
METADATA_XMLNS = 'http://du5t1n.me/xmlns/libvirt/metadata/'
|
||||||
|
|
||||||
|
DOMAIN_STATES = {
|
||||||
|
0: 'no state',
|
||||||
|
1: 'the domain is running',
|
||||||
|
2: 'the domain is blocked on resource',
|
||||||
|
3: 'the domain is paused by user',
|
||||||
|
4: 'the domain is being shut down',
|
||||||
|
5: 'the domain is shut off',
|
||||||
|
6: 'the domain is crashed',
|
||||||
|
7: 'the domain is suspended by guest power management',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the default error handler, which prints to stderr
|
||||||
|
libvirt.registerErrorHandler(lambda *_: None, None)
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
|
NAME = 'pyrocufflink'
|
||||||
|
|
||||||
|
def parse(self, inventory, loader, path, cache=True):
|
||||||
|
super().parse(inventory, loader, path, cache=cache)
|
||||||
|
config_data = self._read_config_data(path)
|
||||||
|
# set _options from config data
|
||||||
|
self._consume_options(config_data)
|
||||||
|
|
||||||
|
assert self.inventory
|
||||||
|
conn = libvirt.open()
|
||||||
|
for dom in conn.listAllDomains():
|
||||||
|
v = {}
|
||||||
|
|
||||||
|
name = v['name'] = dom.name()
|
||||||
|
try:
|
||||||
|
v['title'] = dom.metadata(1, None)
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
log.debug('Could not get title for domain %s: %s', name, e)
|
||||||
|
inventory_hostname = name
|
||||||
|
else:
|
||||||
|
inventory_hostname = v['title']
|
||||||
|
self.inventory.add_host(inventory_hostname)
|
||||||
|
|
||||||
|
try:
|
||||||
|
v['description'] = dom.metadata(0, None)
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
log.debug('Could not get description for %s: %s', name, e)
|
||||||
|
|
||||||
|
try:
|
||||||
|
metadata = dom.metadata(2, METADATA_XMLNS)
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
log.debug(
|
||||||
|
'Could not get extended domain metadata for %s: %s',
|
||||||
|
name,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
v['metadata'] = parse_metadata(metadata)
|
||||||
|
except Exception as e:
|
||||||
|
log.error('Failed to parse metadata for %s: %s', name, e)
|
||||||
|
|
||||||
|
state, reason = dom.state()
|
||||||
|
v['state_code'] = state
|
||||||
|
v['state_reason_code'] = reason
|
||||||
|
try:
|
||||||
|
v['state'] = DOMAIN_STATES[state]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if state == 1:
|
||||||
|
try:
|
||||||
|
guest_info = dom.guestInfo()
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
log.error('Could not get guest info for %s: %s', name, e)
|
||||||
|
else:
|
||||||
|
self.inventory.set_variable(name, 'guest_info', guest_info)
|
||||||
|
self.inventory.set_variable(inventory_hostname, 'libvirt', v)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_metadata(metadata: str):
|
||||||
|
tree = etree.fromstring(metadata)
|
||||||
|
return yaml.safe_load(tree.text)
|
Loading…
Reference in New Issue