#
#

# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Ganeti exception handling.

"""

from ganeti import constants


ECODE_RESOLVER = constants.ERRORS_ECODE_RESOLVER
ECODE_NORES = constants.ERRORS_ECODE_NORES
ECODE_TEMP_NORES = constants.ERRORS_ECODE_TEMP_NORES
ECODE_INVAL = constants.ERRORS_ECODE_INVAL
ECODE_STATE = constants.ERRORS_ECODE_STATE
ECODE_NOENT = constants.ERRORS_ECODE_NOENT
ECODE_EXISTS = constants.ERRORS_ECODE_EXISTS
ECODE_NOTUNIQUE = constants.ERRORS_ECODE_NOTUNIQUE
ECODE_FAULT = constants.ERRORS_ECODE_FAULT
ECODE_ENVIRON = constants.ERRORS_ECODE_ENVIRON
ECODE_ALL = constants.ERRORS_ECODE_ALL


class GenericError(Exception):
  """Base exception for Ganeti.

  """


class LockError(GenericError):
  """Lock error exception.

  This signifies problems in the locking subsystem.

  """


class PidFileLockError(LockError):
  """PID file is already locked by another process.

  """


class HypervisorError(GenericError):
  """Hypervisor-related exception.

  This is raised in case we can't communicate with the hypervisor
  properly.

  """


class HotplugError(HypervisorError):
  """Hotplug-related exception.

  This is raised in case a hotplug action fails or is not supported.
  It is currently used only by KVM hypervisor.

  """


class ProgrammerError(GenericError):
  """Programming-related error.

  This is raised in cases we determine that the calling conventions
  have been violated, meaning we got some desynchronisation between
  parts of our code. It signifies a real programming bug.

  """


class BlockDeviceError(GenericError):
  """Block-device related exception.

  This is raised in case we can't setup the instance's block devices
  properly.

  """


class ConfigurationError(GenericError):
  """Configuration related exception.

  Things like having an instance with a primary node that doesn't
  exist in the config or such raise this exception.

  """


class ConfigVersionMismatch(ConfigurationError):
  """Version mismatch in the configuration file.

  The error has two arguments: the expected and the actual found
  version.

  """


class ConfigVerifyError(ConfigurationError):
  """Error reported by configuration verification

  The error has two arguments: the main error message and a list of errors
  found.

  """


class AddressPoolError(GenericError):
  """Errors related to IP address pools.

  """


class ReservationError(GenericError):
  """Errors reserving a resource.

  """


class RemoteError(GenericError):
  """Programming-related error on remote call.

  This is raised when an unhandled error occurs in a call to a
  remote node.  It usually signifies a real programming bug.

  """


class SignatureError(GenericError):
  """Error authenticating a remote message.

  This is raised when the hmac signature on a message doesn't verify correctly
  to the message itself. It can happen because of network unreliability or
  because of spurious traffic.

  """


class ParameterError(GenericError):
  """A passed parameter to a command is invalid.

  This is raised when the parameter passed to a request function is
  invalid. Correct code should have verified this before passing the
  request structure.

  The argument to this exception should be the parameter name.

  """


class ResultValidationError(GenericError):
  """The iallocation results fails validation.

  """


class OpPrereqError(GenericError):
  """Prerequisites for the OpCode are not fulfilled.

  This exception has two arguments: an error message, and one of the
  ECODE_* codes.

  """


class OpExecError(GenericError):
  """Error during OpCode execution.

  """


class OpResultError(GenericError):
  """Issue with OpCode result.

  """


class OpRetryNotSupportedError(GenericError):
  """This opcode does not support retries

  """


class DeviceCreationError(GenericError):
  """Error during the creation of a device.

  This exception should contain the list of the devices actually created
  up to now, in the form of pairs (node, device)

  """
  def __init__(self, message, created_devices):
    GenericError.__init__(self)
    self.message = message
    self.created_devices = created_devices

  def __str__(self):
    return self.message


class OpCodeUnknown(GenericError):
  """Unknown opcode submitted.

  This signifies a mismatch between the definitions on the client and
  server side.

  """


class JobLost(GenericError):
  """Submitted job lost.

  The job was submitted but it cannot be found in the current job
  list.

  """


class JobCanceled(GenericError):
  """Submitted job was canceled.

  The job that was submitted has transitioned to a canceling or canceled
  state.

  """


class JobFileCorrupted(GenericError):
  """Job file could not be properly decoded/restored.

  """


class ResolverError(GenericError):
  """Host name cannot be resolved.

  This is not a normal situation for Ganeti, as we rely on having a
  working resolver.

  The non-resolvable hostname is available as the first element of the
  args tuple; the other two elements of the tuple are the first two
  args of the socket.gaierror exception (error code and description).

  """


class HooksFailure(GenericError):
  """A generic hook failure.

  This signifies usually a setup misconfiguration.

  """


class HooksAbort(HooksFailure):
  """A required hook has failed.

  This caused an abort of the operation in the initial phase. This
  exception always has an attribute args which is a list of tuples of:
    - node: the source node on which this hooks has failed
    - script: the name of the script which aborted the run

  """


class UnitParseError(GenericError):
  """Unable to parse size unit.

  """


class ParseError(GenericError):
  """Generic parse error.

  Raised when unable to parse user input.

  """


class TypeEnforcementError(GenericError):
  """Unable to enforce data type.

  """


class X509CertError(GenericError):
  """Invalid X509 certificate.

  This error has two arguments: the certificate filename and the error cause.

  """


class TagError(GenericError):
  """Generic tag error.

  The argument to this exception will show the exact error.

  """


class CommandError(GenericError):
  """External command error.

  """


class StorageError(GenericError):
  """Storage-related exception.

  """


class InotifyError(GenericError):
  """Error raised when there is a failure setting up an inotify watcher.

  """


class QuitGanetiException(Exception):
  """Signal Ganeti that it must quit.

  This is not necessarily an error (and thus not a subclass of
  GenericError), but it's an exceptional circumstance and it is thus
  treated. This exception should be instantiated with two values. The
  first one will specify the return code to the caller, and the second
  one will be the returned result (either as an error or as a normal
  result). Usually only the leave cluster rpc call should return
  status True (as there it's expected we quit), every other call will
  return status False (as a critical error was encountered).

  Examples::

    # Return a result of "True" to the caller, but quit ganeti afterwards
    raise QuitGanetiException(True, None)
    # Send an error to the caller, and quit ganeti
    raise QuitGanetiException(False, "Fatal safety violation, shutting down")

  """


class JobQueueError(GenericError):
  """Job queue error.

  """


class JobQueueDrainError(JobQueueError):
  """Job queue is marked for drain error.

  This is raised when a job submission attempt is made but the queue
  is marked for drain.

  """


class JobQueueFull(JobQueueError):
  """Job queue full error.

  Raised when job queue size reached its hard limit.

  """


class ConfdMagicError(GenericError):
  """A magic fourcc error in Ganeti confd.

  Errors processing the fourcc in ganeti confd datagrams.

  """


class ConfdClientError(GenericError):
  """A magic fourcc error in Ganeti confd.

  Errors in the confd client library.

  """


class UdpDataSizeError(GenericError):
  """UDP payload too big.

  """


class NoCtypesError(GenericError):
  """python ctypes module is not found in the system.

  """


class IPAddressError(GenericError):
  """Generic IP address error.

  """


class LuxiError(GenericError):
  """LUXI error.

  """


class QueryFilterParseError(ParseError):
  """Error while parsing query filter.

  This exception must be instantiated with two values. The first one is a
  string with an error description, the second one is an instance of a subclass
  of C{pyparsing.ParseBaseException} (used to display the exact error
  location).

  """
  def GetDetails(self):
    """Returns a list of strings with details about the error.

    """
    try:
      (_, inner) = self.args
    except IndexError:
      return None

    return [str(inner.line),
            (" " * (inner.column - 1)) + "^",
            str(inner)]


class RapiTestResult(GenericError):
  """Exception containing results from RAPI test utilities.

  """


class FileStoragePathError(GenericError):
  """Error from file storage path validation.

  """


class SshUpdateError(GenericError):
  """Error from updating the SSH setup.

  """


class JobSubmittedException(Exception):
  """Job was submitted, client should exit.

  This exception has one argument, the ID of the job that was
  submitted. The handler should print this ID.

  This is not an error, just a structured way to exit from clients.

  """


# errors should be added above


def GetErrorClass(name):
  """Return the class of an exception.

  Given the class name, return the class itself.

  @type name: str
  @param name: the exception name
  @rtype: class
  @return: the actual class, or None if not found

  """
  item = globals().get(name, None)
  if item is not None:
    if not (isinstance(item, type(Exception)) and
            issubclass(item, GenericError)):
      item = None
  return item


def EncodeException(err):
  """Encodes an exception into a format that L{MaybeRaise} will recognise.

  The passed L{err} argument will be formatted as a tuple (exception
  name, arguments) that the MaybeRaise function will recognise.

  @type err: GenericError child
  @param err: usually a child of GenericError (but any exception
      will be accepted)
  @rtype: tuple
  @return: tuple of (exception name, exception arguments)

  """
  return (err.__class__.__name__, err.args)


def GetEncodedError(result):
  """If this looks like an encoded Ganeti exception, return it.

  This function tries to parse the passed argument and if it looks
  like an encoding done by EncodeException, it will return the class
  object and arguments.

  """
  tlt = (tuple, list)
  if (isinstance(result, tlt) and len(result) == 2 and
      isinstance(result[1], tlt)):
    # custom ganeti errors
    errcls = GetErrorClass(result[0])
    if errcls:
      return (errcls, tuple(result[1]))

  return None


def MaybeRaise(result):
  """If this looks like an encoded Ganeti exception, raise it.

  This function tries to parse the passed argument and if it looks
  like an encoding done by EncodeException, it will re-raise it.

  """
  error = GetEncodedError(result)
  if error:
    (errcls, args) = error
    # pylint: disable=W0142
    raise errcls(*args)
