wip: dynamic inventory
parent
143c96074e
commit
ae39d2a232
|
@ -4,6 +4,7 @@
|
|||
inventory = hosts
|
||||
|
||||
callback_plugins = plugins/callback
|
||||
inventory_plugins = plugins/inventory
|
||||
|
||||
gathering = smart
|
||||
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