From f7c8e7bdab579722678764ef0a64ee22804449e7 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 18 Jul 2017 16:50:23 +0530 Subject: [PATCH] Update vmware_inventory (#26308) Fix adds * Exception handling * Unit tests Signed-off-by: Abhijeet Kasurde --- contrib/inventory/vmware_inventory.py | 56 +++++++++++-------- .../inventory/test_vmware_inventory.py | 8 ++- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/contrib/inventory/vmware_inventory.py b/contrib/inventory/vmware_inventory.py index 8ef943819a2..575e3459a67 100755 --- a/contrib/inventory/vmware_inventory.py +++ b/contrib/inventory/vmware_inventory.py @@ -39,14 +39,12 @@ from six.moves import configparser from time import time from jinja2 import Environment -HAS_PYVMOMI = False -try: - from pyVmomi import vim - from pyVim.connect import SmartConnect, Disconnect - HAS_PYVMOMI = True +try: + from pyVmomi import vim, vmodl + from pyVim.connect import SmartConnect, Disconnect except ImportError: - pass + sys.exit("ERROR: This inventory script required 'pyVmomi' Python module, it was not able to load it") try: import json @@ -119,14 +117,12 @@ class VMWareInventory(object): env.filters['regex_match'] = regex_match # translation table for attributes to fetch for known vim types - if not HAS_PYVMOMI: - vimTable = {} - else: - vimTable = { - vim.Datastore: ['_moId', 'name'], - vim.ResourcePool: ['_moId', 'name'], - vim.HostSystem: ['_moId', 'name'], - } + + vimTable = { + vim.Datastore: ['_moId', 'name'], + vim.ResourcePool: ['_moId', 'name'], + vim.HostSystem: ['_moId', 'name'], + } @staticmethod def _empty_inventory(): @@ -347,13 +343,21 @@ class VMWareInventory(object): ''' Make API calls ''' instances = [] - si = SmartConnect(**inkwargs) + try: + si = SmartConnect(**inkwargs) + except ssl.SSLError as connection_error: + if '[SSL: CERTIFICATE_VERIFY_FAILED]' in str(connection_error) and self.validate_certs: + sys.exit("Unable to connect to ESXi server due to %s, " + "please specify validate_certs=False and try again" % connection_error) + + except Exception as exc: + self.debugl("Unable to connect to ESXi server due to %s" % exc) + sys.exit("Unable to connect to ESXi server due to %s" % exc) self.debugl('retrieving all instances') if not si: - print("Could not connect to the specified host using specified " - "username and password") - return -1 + sys.exit("Could not connect to the specified host using specified " + "username and password") atexit.register(Disconnect, si) content = si.RetrieveContent() @@ -384,12 +388,16 @@ class VMWareInventory(object): instance_tuples.append((instance, ifacts)) self.debugl('facts collected for all instances') - cfm = content.customFieldsManager - if cfm is not None and cfm.field: - for f in cfm.field: - if f.managedObjectType == vim.VirtualMachine: - self.custom_fields[f.key] = f.name - self.debugl('%d custom fieds collected' % len(self.custom_fields)) + try: + cfm = content.customFieldsManager + if cfm is not None and cfm.field: + for f in cfm.field: + if f.managedObjectType == vim.VirtualMachine: + self.custom_fields[f.key] = f.name + self.debugl('%d custom fields collected' % len(self.custom_fields)) + except vmodl.RuntimeFault as exc: + self.debugl("Unable to gather custom fields due to %s" % exc.msg) + return instance_tuples def instances_to_inventory(self, instances): diff --git a/test/units/contrib/inventory/test_vmware_inventory.py b/test/units/contrib/inventory/test_vmware_inventory.py index 52e750b844f..8a7df536678 100644 --- a/test/units/contrib/inventory/test_vmware_inventory.py +++ b/test/units/contrib/inventory/test_vmware_inventory.py @@ -3,11 +3,17 @@ import os import pickle import unittest import sys +from nose.plugins.skip import SkipTest + + +try: + from pyVmomi import vim, vmodl +except ImportError: + raise SkipTest("test_vmware_inventory.py requires the python module 'pyVmomi'") try: from vmware_inventory import VMWareInventory except ImportError: - from nose.plugins.skip import SkipTest raise SkipTest("test_vmware_inventory.py requires the python module 'vmware_inventory'") # contrib's dirstruct doesn't contain __init__.py files