Skip to content

Instantly share code, notes, and snippets.

@kondor6c
Created May 16, 2018 02:28
Show Gist options
  • Save kondor6c/6ca54c20fbe781898ef575fe96e7766c to your computer and use it in GitHub Desktop.
Save kondor6c/6ca54c20fbe781898ef575fe96e7766c to your computer and use it in GitHub Desktop.
don't judge, just showing over-use of arg parse
#!/usr/bin/env python3
# TODO: add OSType() features
# influenced by: /usr/share/doc/libvirt-python/examples/domipaddrs.py
# http://muzso.hu/2010/10/29/python-script-to-list-libvirt-domains-with-their-descriptions
# {'vnet1': {'hwaddr': '52:54:00:01:7f:3f', 'addrs': [{'prefix': 24, 'type': 0, 'addr': '192.168.122.168'}]}}
# name, value {'hwaddr': '52:54:00:01:7f:3f', 'addrs': [{'prefix': 24, 'type': 0, 'addr': '192.168.122.168'}]}
#
import libvirt
import argparse
import json
import re
import sys
import xml.etree.ElementTree as ET
def generate_label():
best_effort_label = { "created": "",
"template": False,
"children":
[ ], #any clones taken of storage? if it has clones and is not a clone itself then template is true
"role": "",
"guest":
{
"lsb_release": "",
"agent": False #if channel qemu-ga device is present assume guest
},
"tags":
[
{"ip": ""},
{"additional_disk": ""}
]
}
return best_effort_label
inventory_out = {}
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--all',
dest = 'enable_powered_off_domains',
default = False,
help = 'All domains, even if powered off',
action='store_true')
parser.add_argument('-c', '--connect',
dest = 'uri',
default = 'qemu:///system',
type = str,
help = 'hypervisor connection URI',
metavar = 'URI')
parser.add_argument('-W', '--write-enabled',
dest = 'write_enabled',
default = False,
help = 'connect to libvirt with a read/write permissions',
action='store_true')
parser.add_argument('-d', '--description',
dest = 'description_argument',
default = False,
help = 'print the extended decription, JSON if setup properly',
action='store_true')
parser.add_argument('-C', '--create-label',
dest = 'create_label',
default = False,
help = 'Attempt to create a label for the domain, this could be destructive and needs write enabled connection',
action='store_true')
parser.add_argument('-n', '--no-inventory-output',
dest = 'no_inventory',
default = False,
help = 'prevent the standard Ansible inventory from being displayed',
action='store_true')
parser.add_argument('-p', '--pattern',
default = '.*',
help = 'pattern to search for, default is to output all active',
metavar = 'REGEX')
arg_results = parser.parse_args()
#def get_list(pattern):
try:
lconn = libvirt.openReadOnly(arg_results.uri)
if arg_results.write_enabled is True:
lconn = libvirt.open(arg_results.uri)
except (Exception):
print (sys.stderr, 'print_list: failed to connect to "{0}"'.format(arg_results.uri))
return 1
inventory_list = {}
if arg_results.pattern is None:
arg_results.pattern='.*'
for vm in lconn.listAllDomains():
vm_name = vm.name()
print(vm_name)
powered_on_status = bool(vm.isActive())
print(powered_on_status)
print(vm.isActive())
name_search=re.search(arg_results.pattern, vm_name,flags=re.VERBOSE)
if ( name_search and powered_on_status is True and arg_results.no_inventory != True) :
print( re.search(arg_results.pattern, vm_name,re.VERBOSE))
try:
ifaces = vm.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE, 0);
except:
#This should not be reached, because we test for it at the parent if.
print(sys.stderr, "failed to obtain IP for: " + vm_name)
for (name, val) in ifaces.items(): #ugly... really all of this is
if val['addrs']:
for ipaddr in val['addrs']:
if ipaddr['type'] == libvirt.VIR_IP_ADDR_TYPE_IPV4:
inventory_list[vm_name] = {}
try:
inventory_list[vm_name]=ipaddr['addr'] #no support for multiple interfaces, yet
except KeyError:
if arg_results.create_label is True:
print(generate_label())
if arg_results.write_enabled is True:
print('TODO: write description to Domain/VM')
else:
print('could not handle VM, had no valid JSON "tag"')
if ( arg_results.enable_powered_off_domains is not False and powered_on_status is False ) and arg_results.no_inventory is True:
#Right now, we should only support inventory, we can add a more complete module later. I have a need currently for search=return name:ip .
vm_details = lconn.lookupByName(vm_name).XMLDesc()
vm_xml = ET.fromstring(vm_details)
vm_description = vm_xml.find('description')
if ( vm_description != None and arg_results.description_argument != False ):
inventory_list[vm_name] = json.loads(vm_description.text)
print(inventory_list)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment