From 99e124814c53f46fed135bb1e251112c0025d079 Mon Sep 17 00:00:00 2001 From: Feodor Tersin Date: Fri, 20 Mar 2015 17:24:48 +0300 Subject: [PATCH] Reorganize hierarchy of exception classes Separate ancestors of ec2api internal and aws compliant exceptions. EC2APIException - base exception class for ec2api with formatting support EC2MetadataException - still covers internal exception of ec2api metadata service EC2Exception - still covers AWS compliant exceptions EC2xxxException - derive EC2Exception and are intended to group exceptions by kind Also remove unused attributes and code from base exception class. Fix string constant style to be 'xxx' wherever it's possible. Change-Id: I398c1e8e1816e0d4073fa5d3fdf0c0a939470399 --- ec2api/api/image.py | 3 +- ec2api/api/instance.py | 2 +- ec2api/context.py | 4 +- ec2api/exception.py | 534 +++++++++++++++-------------- ec2api/tests/unit/test_image.py | 4 +- ec2api/tests/unit/test_instance.py | 4 +- ec2api/wsgi.py | 7 +- 7 files changed, 286 insertions(+), 272 deletions(-) diff --git a/ec2api/api/image.py b/ec2api/api/image.py index dd61edd3..5fc3a986 100644 --- a/ec2api/api/image.py +++ b/ec2api/api/image.py @@ -756,7 +756,8 @@ def _s3_test_for_malicious_tarball(path, filename): for n in tar_file.getnames(): if not os.path.abspath(os.path.join(path, n)).startswith(path): tar_file.close() - raise exception.Invalid(_('Unsafe filenames in image')) + # TODO(ft): figure out actual AWS exception + raise exception.EC2InvalidException(_('Unsafe filenames in image')) tar_file.close() diff --git a/ec2api/api/instance.py b/ec2api/api/instance.py index 6b6bc195..ea3eaf48 100644 --- a/ec2api/api/instance.py +++ b/ec2api/api/instance.py @@ -596,7 +596,7 @@ def _parse_image_parameters(context, image_id, kernel_id, ramdisk_id): if _cloud_get_image_state(os_image) != 'available': # TODO(ft): Change the message with the real AWS message msg = _('Image must be available') - raise exception.ImageNotActive(message=msg) + raise exception.InvalidAMIIDUnavailable(message=msg) return os_image, os_kernel_id, os_ramdisk_id diff --git a/ec2api/context.py b/ec2api/context.py index d37ff229..36db0055 100644 --- a/ec2api/context.py +++ b/ec2api/context.py @@ -178,9 +178,9 @@ def get_os_admin_context(): def require_context(ctxt): - """Raise exception.Forbidden() + """Raise exception.AuthFailure() if context is not a user or an admin context. """ if not ctxt.is_admin and not is_user_context(ctxt): - raise exception.Forbidden() + raise exception.AuthFailure() diff --git a/ec2api/exception.py b/ec2api/exception.py index 8802278e..c4759064 100644 --- a/ec2api/exception.py +++ b/ec2api/exception.py @@ -40,40 +40,18 @@ CONF = cfg.CONF CONF.register_opts(exc_log_opts) -class EC2MetadataException(Exception): - pass - - -class EC2MetadataNotFound(EC2MetadataException): - pass - - -class EC2MetadataInvalidAddress(EC2MetadataException): - pass - - -class EC2Exception(Exception): - """Base EC2 Exception +class EC2APIException(Exception): + """Base EC2 API Exception To correctly use this class, inherit from it and define a 'msg_fmt' property. That msg_fmt will get printf'd with the keyword arguments provided to the constructor. - """ - msg_fmt = _("An unknown exception occurred.") - code = 400 - headers = {} - safe = False + msg_fmt = _('An unknown exception occurred.') def __init__(self, message=None, **kwargs): self.kwargs = kwargs - if 'code' not in self.kwargs: - try: - self.kwargs['code'] = self.code - except AttributeError: - pass - if not message: try: message = self.msg_fmt % kwargs @@ -84,7 +62,7 @@ class EC2Exception(Exception): LOG.exception(_('Exception in string format operation for ' '%s exception'), self.__class__.__name__) for name, value in kwargs.iteritems(): - LOG.error("%s: %s" % (name, value)) + LOG.error('%s: %s' % (name, value)) if CONF.fatal_exception_format_errors: raise exc_info[0], exc_info[1], exc_info[2] @@ -100,311 +78,345 @@ class EC2Exception(Exception): else: message = self.msg_fmt - super(EC2Exception, self).__init__(message) + super(EC2APIException, self).__init__(message) def format_message(self): # NOTE(mrodden): use the first argument to the python Exception object - # which should be our full EC2Exception message, (see __init__) + # which should be our full EC2APIException message, (see __init__) return self.args[0] +# Internal ec2api exceptions + +class EC2APIConfigNotFound(EC2APIException): + msg_fmt = _("Could not find config at %(path)s") + + +class EC2APIPasteAppNotFound(EC2APIException): + msg_fmt = _("Could not load paste app '%(name)s' from %(path)s") + + +# Internal ec2api metadata exceptions + +class EC2MetadataException(EC2APIException): + pass + + +class EC2MetadataNotFound(EC2MetadataException): + pass + + +class EC2MetadataInvalidAddress(EC2MetadataException): + pass + + +# Intermediate exception classes to organize AWS exception hierarchy + +class EC2Exception(EC2APIException): + """Base EC2 compliant exception + + To correctly use this class, inherit from it and define + a 'ec2_code' property if a new class name doesn't coincide with + AWS Error Code. + """ + code = 400 + + +class EC2InvalidException(EC2Exception): + pass + + +class EC2IncorrectStateException(EC2Exception): + pass + + +class EC2DuplicateException(EC2InvalidException): + pass + + +class EC2InUseException(EC2InvalidException): + pass + + +class EC2NotFoundException(EC2InvalidException): + pass + + +class EC2OverlimitException(EC2Exception): + pass + + +# AWS compliant exceptions + class Unsupported(EC2Exception): msg_fmt = _("The specified request is unsupported. %(reason)s") -class Overlimit(EC2Exception): - msg_fmt = _("Limit exceeded.") +class UnsupportedOperation(EC2Exception): + msg_fmt = _('The specified request includes an unsupported operation.') -class Invalid(EC2Exception): - msg_fmt = _("Unacceptable parameters.") +class OperationNotPermitted(EC2Exception): + msg_fmt = _('The specified operation is not allowed.') -class InvalidRequest(Invalid): - msg_fmt = _("The request is invalid.") +class InvalidRequest(EC2InvalidException): + msg_fmt = _('The request is invalid.') -class InvalidAttribute(Invalid): +class InvalidAttribute(EC2InvalidException): msg_fmt = _("Attribute not supported: %(attr)s") -class InvalidID(Invalid): +class InvalidID(EC2InvalidException): msg_fmt = _("The ID '%(id)s' is not valid") -class InvalidInput(Invalid): +class InvalidInput(EC2InvalidException): msg_fmt = _("Invalid input received: %(reason)s") -class ConfigNotFound(EC2Exception): - msg_fmt = _("Could not find config at %(path)s") +class AuthFailure(EC2InvalidException): + msg_fmt = _('Not authorized.') -class PasteAppNotFound(EC2Exception): - msg_fmt = _("Could not load paste app '%(name)s' from %(path)s") - - -class Forbidden(EC2Exception): - ec2_code = 'AuthFailure' - msg_fmt = _("Not authorized.") - code = 403 - - -class AuthFailure(Invalid): - pass - - -class ValidationError(Invalid): +class ValidationError(EC2InvalidException): msg_fmt = _("The input fails to satisfy the constraints " "specified by an AWS service: '%(reason)s'") -class EC2NotFound(EC2Exception): - msg_fmt = _("Resource could not be found.") - - -class InvalidInstanceIDNotFound(EC2NotFound): - ec2_code = 'InvalidInstanceID.NotFound' - msg_fmt = _("The instance ID '%(id)s' does not exist") - - -class InvalidVpcIDNotFound(EC2NotFound): - ec2_code = 'InvalidVpcID.NotFound' - msg_fmt = _("The vpc ID '%(id)s' does not exist") - - -class InvalidInternetGatewayIDNotFound(EC2NotFound): - ec2_code = 'InvalidInternetGatewayID.NotFound' - msg_fmt = _("The internetGateway ID '%(id)s' does not exist") - - -class InvalidSubnetIDNotFound(EC2NotFound): - ec2_code = 'InvalidSubnetID.NotFound' - msg_fmt = _("The subnet ID '%(id)s' does not exist") - - -class InvalidNetworkInterfaceIDNotFound(EC2NotFound): - ec2_code = 'InvalidNetworkInterfaceID.NotFound' - msg_fmt = _("Network interface %(id)s could not " - "be found.") - - -class InvalidAttachmentIDNotFound(EC2NotFound): - ec2_code = 'InvalidAttachmentID.NotFound' - msg_fmt = _("Attachment %(id)s could not " - "be found.") - - -class InvalidDhcpOptionsIDNotFound(EC2NotFound): - ec2_code = 'InvalidDhcpOptionsID.NotFound' - msg_fmt = _("The dhcp options ID '%(id)s' does not exist") - - -class InvalidAllocationIDNotFound(EC2NotFound): - ec2_code = 'InvalidAllocationID.NotFound' - msg_fmt = _("The allocation ID '%(id)s' does not exist") - - -class InvalidAssociationIDNotFound(EC2NotFound): - ec2_code = 'InvalidAssociationID.NotFound' - msg_fmt = _("The association ID '%(id)s' does not exist") - - -class InvalidRouteTableIDNotFound(EC2NotFound): - ec2_code = 'InvalidRouteTableID.NotFound' - msg_fmt = _("The routeTable ID '%(id)s' does not exist") - - -class InvalidRouteNotFound(EC2NotFound): - ec2_code = 'InvalidRoute.NotFound' - msg_fmt = _('No route with destination-cidr-block ' - '%(destination_cidr_block)s in route table %(route_table_id)s') - - -class InvalidSecurityGroupIDNotFound(EC2NotFound): - ec2_code = 'InvalidSecurityGroupID.NotFound' - msg_fmt = _("The securityGroup ID '%(id)s' does not exist") - - -class InvalidGroupNotFound(EC2NotFound): - ec2_code = 'InvalidGroup.NotFound' - msg_fmg = _("The security group ID '%(id)s' does not exist") - - -class InvalidPermissionNotFound(EC2NotFound): - ec2_code = 'InvalidPermission.NotFound' - msg_fmg = _("The specified permission does not exist") - - -class InvalidVolumeNotFound(EC2NotFound): - ec2_code = 'InvalidVolume.NotFound' - msg_fmt = _("The volume '%(id)s' does not exist.") - - -class InvalidSnapshotNotFound(EC2NotFound): - ec2_code = 'InvalidSnapshot.NotFound' - msg_fmt = _("Snapshot %(id)s could not be found.") - - -class InvalidAMIIDNotFound(EC2NotFound): - ec2_code = 'InvalidAMIID.NotFound' - msg_fmt = _("The image id '[%(id)s]' does not exist") - - -class InvalidKeypairNotFound(EC2NotFound): - ec2_code = 'InvalidKeyPair.NotFound' - msg_fmt = _("Keypair %(id)s is not found") - - -class InvalidAvailabilityZoneNotFound(EC2NotFound): - ec2_code = 'InvalidAvailabilityZone.NotFound' - msg_fmt = _("Availability zone %(id)s not found") - - -class IncorrectState(EC2Exception): - ec2_code = 'IncorrectState' - msg_fmt = _("The resource is in incorrect state for the request - reason: " - "'%(reason)s'") - - -class IncorrectInstanceState(IncorrectState): - ec2_code = 'IncorrectInstanceState' - msg_fmt = _("The instance '%(instance_id)s' is not in a state from which " - "the requested operation can be performed.") - - -class InvalidVpcRange(Invalid): - ec2_code = 'InvalidVpc.Range' - msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.") - - -class InvalidSubnetRange(Invalid): - ec2_code = 'InvalidSubnet.Range' - msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.") - - -class InvalidSubnetConflict(Invalid): - ec2_code = 'InvalidSubnet.Conflict' - msg_fmt = _("The CIDR '%(cidr_block)s' conflicts with another subnet") - - -class MissingParameter(Invalid): +class MissingParameter(EC2InvalidException): msg_fmt = _("The required parameter '%(param)s' is missing") -class InvalidParameter(Invalid): +class InvalidParameter(EC2InvalidException): msg_fmt = _("The property '%(name)s' is not valid") -class InvalidParameterValue(Invalid): +class InvalidParameterValue(EC2InvalidException): msg_fmt = _("Value (%(value)s) for parameter %(parameter)s is invalid. " "%(reason)s") -class InvalidParameterCombination(Invalid): - pass +class InvalidFilter(EC2InvalidException): + msg_fmt = _('The filter is invalid.') -class UnsupportedOperation(Invalid): - pass +class InvalidParameterCombination(EC2InvalidException): + msg_fmt = _('The combination of parameters in incorrect') -class OperationNotPermitted(Invalid): - pass +class InvalidVpcRange(EC2InvalidException): + ec2_code = 'InvalidVpc.Range' + msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.") -class ResourceAlreadyAssociated(Invalid): - ec2_code = 'Resource.AlreadyAssociated' +class InvalidSubnetRange(EC2InvalidException): + ec2_code = 'InvalidSubnet.Range' + msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.") -class GatewayNotAttached(Invalid): - ec2_code = 'Gateway.NotAttached' - msg_fmt = _("resource %(igw_id)s is not attached to network %(vpc_id)s") +class InvalidSubnetConflict(EC2InvalidException): + ec2_code = 'InvalidSubnet.Conflict' + msg_fmt = _("The CIDR '%(cidr_block)s' conflicts with another subnet") -class DependencyViolation(Invalid): - msg_fmt = _('Object %(obj1_id)s has dependent resource %(obj2_id)s') - - -class InvalidNetworkInterfaceInUse(Invalid): - ec2_code = 'InvalidNetworkInterface.InUse' - msg_fmt = _('Interface: %(interface_ids)s in use.') - - -class InvalidInstanceId(Invalid): +class InvalidInstanceId(EC2InvalidException): ec2_code = 'InvalidInstanceID' msg_fmt = _("There are multiple interfaces attached to instance " "'%(instance_id)s'. Please specify an interface ID for " "the operation instead.") -class InvalidIPAddressInUse(Invalid): - ec2_code = 'InvalidIPAddress.InUse' - msg_fmt = _('Address %(ip_address)s is in use.') - - -class InvalidAddressNotFound(Invalid): - ec2_code = 'InvalidAddress.NotFound' - msg_fmt = _('The specified elastic IP address %(ip)s cannot be found.') - - -class RouteAlreadyExists(Invalid): - msg_fmt = _('The route identified by %(destination_cidr_block)s ' - 'already exists.') - - -class VpcLimitExceeded(Overlimit): - msg_fmt = _('The maximum number of VPCs has been reached.') - - -class SubnetLimitExceeded(Overlimit): - msg_fmt = _('You have reached the limit on the number of subnets that you ' - 'can create') - - -class NetworkInterfaceLimitExceeded(Overlimit): - msg_fmt = _('You have reached the limit of network interfaces for subnet' - '%(subnet_id)s.') - - -class ResourceLimitExceeded(Overlimit): - msg_fmt = _('You have reached the limit of %(resource)s') - - -class SecurityGroupLimitExceeded(Overlimit): - msg_fmt = _('You have reached the limit of security groups') - - -class AddressLimitExceeded(Overlimit): - msg_fmt = _('The maximum number of addresses has been reached.') - - -class ImageNotActive(Invalid): - ec2_code = 'InvalidAMIID.Unavailable' - # TODO(ft): Change the message with the real AWS message - msg_fmt = _("Image %(image_id)s is not active.") - - -class InvalidSnapshotIDMalformed(Invalid): +class InvalidSnapshotIDMalformed(EC2InvalidException): ec2_code = 'InvalidSnapshotID.Malformed' # TODO(ft): Change the message with the real AWS message msg_fmg = _('The snapshot %(id)s ID is not valid') -class InvalidKeyPairDuplicate(Invalid): +class IncorrectState(EC2IncorrectStateException): + msg_fmt = _("The resource is in incorrect state for the request - reason: " + "'%(reason)s'") + + +class DependencyViolation(EC2IncorrectStateException): + msg_fmt = _('Object %(obj1_id)s has dependent resource %(obj2_id)s') + + +class ResourceAlreadyAssociated(EC2IncorrectStateException): + ec2_code = 'Resource.AlreadyAssociated' + + +class GatewayNotAttached(EC2IncorrectStateException): + ec2_code = 'Gateway.NotAttached' + msg_fmt = _("resource %(igw_id)s is not attached to network %(vpc_id)s") + + +class IncorrectInstanceState(EC2IncorrectStateException): + msg_fmt = _("The instance '%(instance_id)s' is not in a state from which " + "the requested operation can be performed.") + + +class InvalidAMIIDUnavailable(EC2IncorrectStateException): + ec2_code = 'InvalidAMIID.Unavailable' + # TODO(ft): Change the message with the real AWS message + msg_fmt = _("Image %(image_id)s is not active.") + + +class InvalidNetworkInterfaceInUse(EC2InUseException): + ec2_code = 'InvalidNetworkInterface.InUse' + msg_fmt = _('Interface: %(interface_ids)s in use.') + + +class InvalidIPAddressInUse(EC2InUseException): + ec2_code = 'InvalidIPAddress.InUse' + msg_fmt = _('Address %(ip_address)s is in use.') + + +class InvalidKeyPairDuplicate(EC2DuplicateException): ec2_code = 'InvalidKeyPair.Duplicate' msg_fmt = _("Key pair '%(key_name)s' already exists.") -class InvalidPermissionDuplicate(Invalid): +class InvalidPermissionDuplicate(EC2DuplicateException): ec2_code = 'InvalidPermission.Duplicate' - msg_fmt = _("The specified rule already exists for that security group.") + msg_fmt = _('The specified rule already exists for that security group.') -class InvalidFilter(Invalid): - msg_fmt = _("The filter is invalid.") +class RouteAlreadyExists(EC2DuplicateException): + msg_fmt = _('The route identified by %(destination_cidr_block)s ' + 'already exists.') -class RulesPerSecurityGroupLimitExceeded(Overlimit): +class InvalidVpcIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidVpcID.NotFound' + msg_fmt = _("The vpc ID '%(id)s' does not exist") + + +class InvalidInternetGatewayIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidInternetGatewayID.NotFound' + msg_fmt = _("The internetGateway ID '%(id)s' does not exist") + + +class InvalidSubnetIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidSubnetID.NotFound' + msg_fmt = _("The subnet ID '%(id)s' does not exist") + + +class InvalidNetworkInterfaceIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidNetworkInterfaceID.NotFound' + msg_fmt = _("Network interface %(id)s could not " + "be found.") + + +class InvalidAttachmentIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidAttachmentID.NotFound' + msg_fmt = _("Attachment %(id)s could not " + "be found.") + + +class InvalidInstanceIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidInstanceID.NotFound' + msg_fmt = _("The instance ID '%(id)s' does not exist") + + +class InvalidDhcpOptionsIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidDhcpOptionsID.NotFound' + msg_fmt = _("The dhcp options ID '%(id)s' does not exist") + + +class InvalidAddressNotFound(EC2NotFoundException): + ec2_code = 'InvalidAddress.NotFound' + msg_fmt = _('The specified elastic IP address %(ip)s cannot be found.') + + +class InvalidAllocationIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidAllocationID.NotFound' + msg_fmt = _("The allocation ID '%(id)s' does not exist") + + +class InvalidAssociationIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidAssociationID.NotFound' + msg_fmt = _("The association ID '%(id)s' does not exist") + + +class InvalidSecurityGroupIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidSecurityGroupID.NotFound' + msg_fmt = _("The securityGroup ID '%(id)s' does not exist") + + +class InvalidGroupNotFound(EC2NotFoundException): + ec2_code = 'InvalidGroup.NotFound' + msg_fmg = _("The security group ID '%(id)s' does not exist") + + +class InvalidPermissionNotFound(EC2NotFoundException): + ec2_code = 'InvalidPermission.NotFound' + msg_fmg = _('The specified permission does not exist') + + +class InvalidRouteTableIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidRouteTableID.NotFound' + msg_fmt = _("The routeTable ID '%(id)s' does not exist") + + +class InvalidRouteNotFound(EC2NotFoundException): + ec2_code = 'InvalidRoute.NotFound' + msg_fmt = _('No route with destination-cidr-block ' + '%(destination_cidr_block)s in route table %(route_table_id)s') + + +class InvalidAMIIDNotFound(EC2NotFoundException): + ec2_code = 'InvalidAMIID.NotFound' + msg_fmt = _("The image id '[%(id)s]' does not exist") + + +class InvalidVolumeNotFound(EC2NotFoundException): + ec2_code = 'InvalidVolume.NotFound' + msg_fmt = _("The volume '%(id)s' does not exist.") + + +class InvalidSnapshotNotFound(EC2NotFoundException): + ec2_code = 'InvalidSnapshot.NotFound' + msg_fmt = _("Snapshot %(id)s could not be found.") + + +class InvalidKeypairNotFound(EC2NotFoundException): + ec2_code = 'InvalidKeyPair.NotFound' + msg_fmt = _("Keypair %(id)s is not found") + + +class InvalidAvailabilityZoneNotFound(EC2NotFoundException): + ec2_code = 'InvalidAvailabilityZone.NotFound' + msg_fmt = _("Availability zone %(id)s not found") + + +class ResourceLimitExceeded(EC2OverlimitException): + msg_fmt = _('You have reached the limit of %(resource)s') + + +class VpcLimitExceeded(EC2OverlimitException): + msg_fmt = _('The maximum number of VPCs has been reached.') + + +class SubnetLimitExceeded(EC2OverlimitException): + msg_fmt = _('You have reached the limit on the number of subnets that you ' + 'can create') + + +class NetworkInterfaceLimitExceeded(EC2OverlimitException): + msg_fmt = _('You have reached the limit of network interfaces for subnet' + '%(subnet_id)s.') + + +class AddressLimitExceeded(EC2OverlimitException): + msg_fmt = _('The maximum number of addresses has been reached.') + + +class SecurityGroupLimitExceeded(EC2OverlimitException): + msg_fmt = _('You have reached the limit of security groups') + + +class RulesPerSecurityGroupLimitExceeded(EC2OverlimitException): msg_fmt = _("You've reached the limit on the number of rules that " "you can add to a security group.") diff --git a/ec2api/tests/unit/test_image.py b/ec2api/tests/unit/test_image.py index 6aaafc55..b677cd2f 100644 --- a/ec2api/tests/unit/test_image.py +++ b/ec2api/tests/unit/test_image.py @@ -613,10 +613,10 @@ class S3TestCase(base.ApiTestCase): def test_s3_malicious_tarballs(self): self.assertRaises( - exception.Invalid, + exception.EC2InvalidException, image_api._s3_test_for_malicious_tarball, "/unused", os.path.join(os.path.dirname(__file__), 'abs.tar.gz')) self.assertRaises( - exception.Invalid, + exception.EC2InvalidException, image_api._s3_test_for_malicious_tarball, "/unused", os.path.join(os.path.dirname(__file__), 'rel.tar.gz')) diff --git a/ec2api/tests/unit/test_instance.py b/ec2api/tests/unit/test_instance.py index 4967d4ed..a8ed06cc 100644 --- a/ec2api/tests/unit/test_instance.py +++ b/ec2api/tests/unit/test_instance.py @@ -1478,7 +1478,7 @@ class InstancePrivateTestCase(test_base.BaseTestCase): get_os_image.return_value = os_image self.assertRaises( - exception.ImageNotActive, + exception.InvalidAMIIDUnavailable, instance_api._parse_image_parameters, fake_context, fakes.random_ec2_id('ami'), None, None) @@ -1486,7 +1486,7 @@ class InstancePrivateTestCase(test_base.BaseTestCase): os_image.properties['image_state'] = 'decrypting' self.assertRaises( - exception.ImageNotActive, + exception.InvalidAMIIDUnavailable, instance_api._parse_image_parameters, fake_context, fakes.random_ec2_id('ami'), None, None) diff --git a/ec2api/wsgi.py b/ec2api/wsgi.py index e2ad3b6b..bccff82e 100644 --- a/ec2api/wsgi.py +++ b/ec2api/wsgi.py @@ -484,14 +484,14 @@ class Loader(object): self.config_path = config_path if not self.config_path: - raise exception.ConfigNotFound(path=config_path) + raise exception.EC2APIConfigNotFound(path=config_path) def load_app(self, name): """Return the paste URLMap wrapped WSGI application. :param name: Name of the application to load. :returns: Paste URLMap object wrapping the requested application. - :raises: `ec2api.exception.PasteAppNotFound` + :raises: `ec2api.exception.EC2APIPasteAppNotFound` """ try: @@ -500,4 +500,5 @@ class Loader(object): return deploy.loadapp("config:%s" % self.config_path, name=name) except LookupError as err: LOG.error(err) - raise exception.PasteAppNotFound(name=name, path=self.config_path) + raise exception.EC2APIPasteAppNotFound(name=name, + path=self.config_path)