54690d1095
Change-Id: I0e090f1d8dca70235615242f8993081c71ae6615
437 lines
13 KiB
Python
437 lines
13 KiB
Python
# Copyright 2014
|
|
# The Cloudscaling Group, Inc.
|
|
#
|
|
# 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.
|
|
|
|
"""ec2api base exception handling.
|
|
|
|
Includes decorator for re-raising ec2api-type exceptions.
|
|
|
|
SHOULD include dedicated exception logging.
|
|
|
|
"""
|
|
|
|
import sys
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
import six
|
|
|
|
from ec2api.i18n import _
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
exc_log_opts = [
|
|
cfg.BoolOpt('fatal_exception_format_errors',
|
|
default=False,
|
|
help='Make exception message format errors fatal'),
|
|
]
|
|
|
|
CONF = cfg.CONF
|
|
CONF.register_opts(exc_log_opts)
|
|
|
|
|
|
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.')
|
|
|
|
def __init__(self, message=None, **kwargs):
|
|
self.kwargs = kwargs
|
|
|
|
if not message:
|
|
try:
|
|
message = self.msg_fmt % kwargs
|
|
except Exception:
|
|
exc_info = sys.exc_info()
|
|
# kwargs doesn't match a variable in the message
|
|
# log the issue and the kwargs
|
|
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))
|
|
|
|
if CONF.fatal_exception_format_errors:
|
|
raise exc_info[0], exc_info[1], exc_info[2]
|
|
else:
|
|
# at least get the core message out if something happened
|
|
message = self.msg_fmt
|
|
elif not isinstance(message, six.string_types):
|
|
LOG.error(_("Message '%(msg)s' for %(ex)s exception is not "
|
|
"a string"),
|
|
{'msg': message, 'ex': self.__class__.__name__})
|
|
if CONF.fatal_exception_format_errors:
|
|
raise TypeError(_('Invalid exception message format'))
|
|
else:
|
|
message = self.msg_fmt
|
|
|
|
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 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 UnsupportedOperation(EC2Exception):
|
|
msg_fmt = _('The specified request includes an unsupported operation.')
|
|
|
|
|
|
class OperationNotPermitted(EC2Exception):
|
|
msg_fmt = _('The specified operation is not allowed.')
|
|
|
|
|
|
class InvalidRequest(EC2InvalidException):
|
|
msg_fmt = _('The request received was invalid.')
|
|
|
|
|
|
class InvalidAttribute(EC2InvalidException):
|
|
msg_fmt = _("Attribute not supported: %(attr)s")
|
|
|
|
|
|
class InvalidID(EC2InvalidException):
|
|
msg_fmt = _("The ID '%(id)s' is not valid")
|
|
|
|
|
|
class InvalidInput(EC2InvalidException):
|
|
msg_fmt = _("Invalid input received: %(reason)s")
|
|
|
|
|
|
class AuthFailure(EC2InvalidException):
|
|
msg_fmt = _('Not authorized.')
|
|
|
|
|
|
class ValidationError(EC2InvalidException):
|
|
msg_fmt = _("The input fails to satisfy the constraints "
|
|
"specified by an AWS service: '%(reason)s'")
|
|
|
|
|
|
class MissingParameter(EC2InvalidException):
|
|
msg_fmt = _("The required parameter '%(param)s' is missing")
|
|
|
|
|
|
class InvalidParameter(EC2InvalidException):
|
|
msg_fmt = _("The property '%(name)s' is not valid")
|
|
|
|
|
|
class InvalidParameterValue(EC2InvalidException):
|
|
msg_fmt = _("Value (%(value)s) for parameter %(parameter)s is invalid. "
|
|
"%(reason)s")
|
|
|
|
|
|
class InvalidFilter(EC2InvalidException):
|
|
msg_fmt = _('The filter is invalid.')
|
|
|
|
|
|
class InvalidParameterCombination(EC2InvalidException):
|
|
msg_fmt = _('The combination of parameters in incorrect')
|
|
|
|
|
|
class InvalidVpcRange(EC2InvalidException):
|
|
ec2_code = 'InvalidVpc.Range'
|
|
msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.")
|
|
|
|
|
|
class InvalidSubnetRange(EC2InvalidException):
|
|
ec2_code = 'InvalidSubnet.Range'
|
|
msg_fmt = _("The CIDR '%(cidr_block)s' is invalid.")
|
|
|
|
|
|
class InvalidSubnetConflict(EC2InvalidException):
|
|
ec2_code = 'InvalidSubnet.Conflict'
|
|
msg_fmt = _("The CIDR '%(cidr_block)s' conflicts with another subnet")
|
|
|
|
|
|
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 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 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 CannotDelete(EC2IncorrectStateException):
|
|
msg_fmt = _('Cannot delete the default VPC security group')
|
|
|
|
|
|
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(EC2DuplicateException):
|
|
ec2_code = 'InvalidPermission.Duplicate'
|
|
msg_fmt = _('The specified rule already exists for that security group.')
|
|
|
|
|
|
class InvalidGroupDuplicate(EC2DuplicateException):
|
|
ec2_code = 'InvalidGroup.Duplicate'
|
|
msg_fmt = _("Security group '%(name)s' already exists.")
|
|
|
|
|
|
class RouteAlreadyExists(EC2DuplicateException):
|
|
msg_fmt = _('The route identified by %(destination_cidr_block)s '
|
|
'already exists.')
|
|
|
|
|
|
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 InvalidCustomerGatewayIDNotFound(EC2NotFoundException):
|
|
ec2_code = 'InvalidCustomerGatewayID.NotFound'
|
|
msg_fmt = _("The customerGateway ID '%(id)s' does not exist")
|
|
|
|
|
|
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.")
|