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
changes/33/139633/8
Peter Razumovsky 8 years ago
parent 6ca66128f1
commit d50aca8d21
  1. 2
      heat/api/aws/exception.py
  2. 1
      heat/api/middleware/fault.py
  3. 10
      heat/common/exception.py
  4. 5
      heat/engine/resources/eip.py
  5. 7
      heat/engine/resources/neutron/neutron.py
  6. 4
      heat/engine/resources/neutron/router.py
  7. 12
      heat/tests/test_eip.py
  8. 8
      heat/tests/test_neutron.py

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

@ -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):

@ -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.

@ -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

@ -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):

@ -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)

@ -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]

@ -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):

Loading…
Cancel
Save