nova/nova/virt/vmwareapi/error_util.py

236 lines
7.5 KiB
Python

# Copyright (c) 2011 Citrix Systems, Inc.
# Copyright 2011 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Exception classes and SOAP response error checking module.
"""
from nova import exception
from nova.i18n import _
from nova.openstack.common import log as logging
LOG = logging.getLogger(__name__)
ALREADY_EXISTS = 'AlreadyExists'
CANNOT_DELETE_FILE = 'CannotDeleteFile'
FILE_ALREADY_EXISTS = 'FileAlreadyExists'
FILE_FAULT = 'FileFault'
FILE_LOCKED = 'FileLocked'
FILE_NOT_FOUND = 'FileNotFound'
INVALID_POWER_STATE = 'InvalidPowerState'
INVALID_PROPERTY = 'InvalidProperty'
NO_PERMISSION = 'NoPermission'
NOT_AUTHENTICATED = 'NotAuthenticated'
TASK_IN_PROGRESS = 'TaskInProgress'
class VimException(Exception):
"""The VIM Exception class."""
def __init__(self, exception_summary, excep):
Exception.__init__(self)
if isinstance(exception_summary, list):
# we need this to protect against developers using
# this method like VimFaultException
raise ValueError(_("exception_summary must not be a list"))
self.exception_summary = str(exception_summary)
self.exception_obj = excep
def __str__(self):
return self.exception_summary + ": " + str(self.exception_obj)
class SessionOverLoadException(VimException):
"""Session Overload Exception."""
pass
class SessionConnectionException(VimException):
"""Session Connection Exception."""
pass
class VimAttributeError(VimException):
"""VI Attribute Error."""
pass
class VimFaultException(Exception):
"""The VIM Fault exception class."""
def __init__(self, fault_list, fault_string, details=None):
Exception.__init__(self)
if not isinstance(fault_list, list):
raise ValueError(_("fault_list must be a list"))
self.fault_list = fault_list
self.fault_string = fault_string
self.details = details
def __str__(self):
if self.details:
return '%s %s' % (self.fault_string, self.details)
return self.fault_string
class FaultCheckers(object):
"""Methods for fault checking of SOAP response. Per Method error handlers
for which we desire error checking are defined. SOAP faults are
embedded in the SOAP messages as properties and not as SOAP faults.
"""
@staticmethod
def retrievepropertiesex_fault_checker(resp_obj):
"""Checks the RetrievePropertiesEx response for errors. Certain faults
are sent as part of the SOAP body as property of missingSet.
For example NotAuthenticated fault.
"""
fault_list = []
details = {}
if not resp_obj:
# This is the case when the session has timed out. ESX SOAP server
# sends an empty RetrievePropertiesResponse. Normally missingSet in
# the returnval field has the specifics about the error, but that's
# not the case with a timed out idle session. It is as bad as a
# terminated session for we cannot use the session. So setting
# fault to NotAuthenticated fault.
fault_list = [NOT_AUTHENTICATED]
else:
for obj_cont in resp_obj.objects:
if hasattr(obj_cont, "missingSet"):
for missing_elem in obj_cont.missingSet:
fault_type = missing_elem.fault.fault
# Fault needs to be added to the type of fault for
# uniformity in error checking as SOAP faults define
fault_list.append(fault_type.__class__.__name__)
if fault_type.__class__.__name__ == NO_PERMISSION:
details['object'] = fault_type.object.value
details['privilegeId'] = fault_type.privilegeId
if fault_list:
exc_msg_list = ', '.join(fault_list)
fault_string = _("Error(s) %s occurred in the call to "
"RetrievePropertiesEx") % exc_msg_list
raise VimFaultException(fault_list, fault_string, details)
class VMwareDriverException(exception.NovaException):
"""Base class for all exceptions raised by the VMware Driver.
All exceptions raised by the VMwareAPI drivers should raise
an exception descended from this class as a root. This will
allow the driver to potentially trap problems related to its
own internal configuration before halting the nova-compute
node.
"""
msg_fmt = _("VMware Driver fault.")
class VMwareDriverConfigurationException(VMwareDriverException):
"""Base class for all configuration exceptions.
"""
msg_fmt = _("VMware Driver configuration fault.")
class UseLinkedCloneConfigurationFault(VMwareDriverConfigurationException):
msg_fmt = _("No default value for use_linked_clone found.")
class MissingParameter(VMwareDriverException):
msg_fmt = _("Missing parameter : %(param)s")
class NoRootDiskDefined(VMwareDriverException):
msg_fmt = _("No root disk defined.")
class AlreadyExistsException(VMwareDriverException):
msg_fmt = _("Resource already exists.")
code = 409
class CannotDeleteFileException(VMwareDriverException):
msg_fmt = _("Cannot delete file.")
code = 403
class FileAlreadyExistsException(VMwareDriverException):
msg_fmt = _("File already exists.")
code = 409
class FileFaultException(VMwareDriverException):
msg_fmt = _("File fault.")
code = 409
class FileLockedException(VMwareDriverException):
msg_fmt = _("File locked.")
code = 403
class FileNotFoundException(VMwareDriverException):
msg_fmt = _("File not found.")
code = 404
class InvalidPropertyException(VMwareDriverException):
msg_fmt = _("Invalid property.")
code = 400
class NoPermissionException(VMwareDriverException):
msg_fmt = _("No Permission.")
code = 403
class NotAuthenticatedException(VMwareDriverException):
msg_fmt = _("Not Authenticated.")
code = 403
class InvalidPowerStateException(VMwareDriverException):
msg_fmt = _("Invalid Power State.")
code = 409
class TaskInProgress(VMwareDriverException):
msg_fmt = _("Virtual machine is busy.")
# Populate the fault registry with the exceptions that have
# special treatment.
_fault_classes_registry = {
ALREADY_EXISTS: AlreadyExistsException,
CANNOT_DELETE_FILE: CannotDeleteFileException,
FILE_ALREADY_EXISTS: FileAlreadyExistsException,
FILE_FAULT: FileFaultException,
FILE_LOCKED: FileLockedException,
FILE_NOT_FOUND: FileNotFoundException,
INVALID_POWER_STATE: InvalidPowerStateException,
INVALID_PROPERTY: InvalidPropertyException,
NO_PERMISSION: NoPermissionException,
NOT_AUTHENTICATED: NotAuthenticatedException,
TASK_IN_PROGRESS: TaskInProgress,
}
def get_fault_class(name):
"""Get a named subclass of VMwareDriverException."""
name = str(name)
fault_class = _fault_classes_registry.get(name)
if not fault_class:
LOG.warning(_('Fault %s not matched.'), name)
fault_class = VMwareDriverException
return fault_class