Add PropertyUnspecifiedError exception

If we have situation, when we must specify at
least one of two conflicted resources, and there
is no specified resource, we get StackValidationFailed
with error msg looks like 'Either resource_1 or
resource_2 must be specified'. There are a few places,
where this situation appears. So it will be reasonable
to add special exception for these situations.

Change-Id: Ib107eff4fe8030fdbb40aa267b9e2b394ff7a186
This commit is contained in:
Peter Razumovsky 2014-12-05 16:55:11 +03:00
parent 6ca66128f1
commit d50aca8d21
8 changed files with 33 additions and 16 deletions

View File

@ -300,6 +300,8 @@ def map_remote_error(ex):
'UserParameterMissing',
'InvalidTemplateParameter',
'MissingCredentialError',
'ResourcePropertyConflict',
'PropertyUnspecifiedError',
)
denied_errors = ('Forbidden', 'NotAuthorized')
already_exists_errors = ('StackExists')

View File

@ -86,6 +86,7 @@ class FaultWrapper(wsgi.Middleware):
'InvalidTemplateParameter': webob.exc.HTTPBadRequest,
'Invalid': webob.exc.HTTPBadRequest,
'ResourcePropertyConflict': webob.exc.HTTPBadRequest,
'PropertyUnspecifiedError': webob.exc.HTTPBadRequest,
}
def _map_exception_to_error(self, class_exception):

View File

@ -323,6 +323,16 @@ class ResourcePropertyConflict(HeatException):
super(ResourcePropertyConflict, self).__init__(**kwargs)
class PropertyUnspecifiedError(HeatException):
msg_fmt = _('At least one of the following properties '
'must be specified: %(props)s')
def __init__(self, *args, **kwargs):
if args:
kwargs.update({'props': ", ".join(args)})
super(PropertyUnspecifiedError, self).__init__(**kwargs)
class HTTPExceptionDisguise(Exception):
"""Disguises HTTP exceptions so they can be handled by the webob fault
application in the wsgi pipeline.

View File

@ -239,9 +239,8 @@ class ElasticIpAssociation(resource.Resource):
# to check InstanceId and NetworkInterfaceId, should provide
# at least one
if not instance_id and not ni_id:
msg = _("Must specify at least one of 'InstanceId' "
"or 'NetworkInterfaceId'.")
raise exception.StackValidationFailed(message=msg)
raise exception.PropertyUnspecifiedError('InstanceId',
'NetworkInterfaceId')
def _get_port_info(self, ni_id=None, instance_id=None):
port_id = None

View File

@ -59,11 +59,8 @@ class NeutronResource(resource.Resource):
raise exception.ResourcePropertyConflict(prop_key,
depr_prop_key)
if not prop_value and not depr_prop_value:
msg = _('Either %(prop_key)s or %(depr_prop_key)s'
' should be specified.'
) % {'prop_key': prop_key,
'depr_prop_key': depr_prop_key}
raise exception.StackValidationFailed(message=msg)
raise exception.PropertyUnspecifiedError(prop_key,
depr_prop_key)
@staticmethod
def prepare_properties(properties, name):

View File

@ -244,8 +244,8 @@ class RouterInterface(neutron.NeutronResource):
raise exception.ResourcePropertyConflict(self.SUBNET,
self.PORT_ID)
if not prop_subnet_exists and not port_id:
msg = 'Either subnet or port_id must be specified.'
raise exception.StackValidationFailed(message=msg)
raise exception.PropertyUnspecifiedError(self.SUBNET,
self.PORT_ID)
def handle_create(self):
router_id = self.properties.get(self.ROUTER_ID)

View File

@ -683,9 +683,15 @@ class AllocTest(common.HeatTestCase):
properties.pop('EIP')
allocation_id = '1fafbe59-2332-4f5f-bfa4-517b4d6c1b65'
properties['AllocationId'] = allocation_id
expected = ("Must specify at least one of 'InstanceId' "
"or 'NetworkInterfaceId'.")
self._validate_properties(stack, template, expected)
resource_defns = template.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation('validate_eip_ass',
resource_defns['IPAssoc'],
stack)
exc = self.assertRaises(exception.PropertyUnspecifiedError,
rsrc.validate)
self.assertIn('At least one of the following properties '
'must be specified: InstanceId, NetworkInterfaceId',
six.text_type(exc))
def test_delete_association_successful_if_create_failed(self):
server = self.fc.servers.list()[0]

View File

@ -551,7 +551,7 @@ class NeutronTest(common.HeatTestCase):
p, 'network', 'network_id')
data = {}
p = properties.Properties(subnet.Subnet.properties_schema, data)
self.assertRaises(exception.StackValidationFailed,
self.assertRaises(exception.PropertyUnspecifiedError,
nr.NeutronResource._validate_depr_property_required,
p, 'network', 'network_id')
@ -1687,8 +1687,10 @@ class NeutronRouterTest(common.HeatTestCase):
res = router.RouterInterface('router_interface',
resource_defns['router_interface'],
stack)
ex = self.assertRaises(exception.StackValidationFailed, res.validate)
self.assertEqual("Either subnet or port_id must be specified.",
ex = self.assertRaises(exception.PropertyUnspecifiedError,
res.validate)
self.assertEqual("At least one of the following properties "
"must be specified: subnet, port_id",
six.text_type(ex))
def test_gateway_router(self):