Report PortLimitExceeded error to customer
When share creation fails due to missing ports quota ( 'manila.exception.PortLimitExceeded: Maximum number of ports exceeded.'), error message propogated to user is not useful. Improve user message in this scenario. Closes-bug: #2019846 Change-Id: I1f010c4ff9faf837bd50b6c2823cbc526f3a42df
This commit is contained in:
parent
b3951d06dd
commit
a372e53098
@ -141,6 +141,13 @@ class Detail(object):
|
|||||||
DRIVER_FAILED_TRANSFER_ACCEPT = (
|
DRIVER_FAILED_TRANSFER_ACCEPT = (
|
||||||
'026',
|
'026',
|
||||||
_("Share transfer cannot be accepted without clearing access rules."))
|
_("Share transfer cannot be accepted without clearing access rules."))
|
||||||
|
SHARE_NETWORK_PORT_QUOTA_LIMIT_EXCEEDED = (
|
||||||
|
'027',
|
||||||
|
_("Failed to create a new network port on the share network subnet. "
|
||||||
|
"The limit of the number of ports has been exceeded. You may "
|
||||||
|
"increase the network port quotas or free up some ports and retry. "
|
||||||
|
"If this doesn't work, contact your administrator to troubleshoot "
|
||||||
|
"issues with your network."))
|
||||||
|
|
||||||
ALL = (
|
ALL = (
|
||||||
UNKNOWN_ERROR,
|
UNKNOWN_ERROR,
|
||||||
@ -169,6 +176,7 @@ class Detail(object):
|
|||||||
NO_DEFAULT_SHARE_TYPE,
|
NO_DEFAULT_SHARE_TYPE,
|
||||||
MISSING_SECURITY_SERVICE,
|
MISSING_SECURITY_SERVICE,
|
||||||
DRIVER_FAILED_TRANSFER_ACCEPT,
|
DRIVER_FAILED_TRANSFER_ACCEPT,
|
||||||
|
SHARE_NETWORK_PORT_QUOTA_LIMIT_EXCEEDED,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Exception and detail mappings
|
# Exception and detail mappings
|
||||||
|
@ -2048,6 +2048,23 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||||||
share_group=share_group_ref,
|
share_group=share_group_ref,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
except exception.PortLimitExceeded:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
error = ("Creation of share instance %s failed: "
|
||||||
|
"failed to allocate network")
|
||||||
|
LOG.error(error, share_instance_id)
|
||||||
|
self.db.share_instance_update(
|
||||||
|
context, share_instance_id,
|
||||||
|
{'status': constants.STATUS_ERROR}
|
||||||
|
)
|
||||||
|
self.message_api.create(
|
||||||
|
context,
|
||||||
|
message_field.Action.CREATE,
|
||||||
|
share['project_id'],
|
||||||
|
resource_type=message_field.Resource.SHARE,
|
||||||
|
resource_id=share_id,
|
||||||
|
detail=(message_field.Detail
|
||||||
|
.SHARE_NETWORK_PORT_QUOTA_LIMIT_EXCEEDED))
|
||||||
except exception.SecurityServiceFailedAuth:
|
except exception.SecurityServiceFailedAuth:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
error = ("Provision of share server failed: "
|
error = ("Provision of share server failed: "
|
||||||
|
@ -2163,6 +2163,69 @@ class ShareManagerTestCase(test.TestCase):
|
|||||||
share_id).id)
|
share_id).id)
|
||||||
manager.LOG.info.assert_called_with(mock.ANY, share.instance['id'])
|
manager.LOG.info.assert_called_with(mock.ANY, share.instance['id'])
|
||||||
|
|
||||||
|
def test_create_share_instance_with_network_port_limit_exceeded(self):
|
||||||
|
share_network = db_utils.create_share_network(id='fake_sn_id')
|
||||||
|
share_net_subnet = db_utils.create_share_network_subnet(
|
||||||
|
id='fake_sns_id', share_network_id=share_network['id']
|
||||||
|
)
|
||||||
|
fake_share = db_utils.create_share(
|
||||||
|
share_network_id=share_network['id'], size=1)
|
||||||
|
fake_metadata = {
|
||||||
|
'request_host': 'fake_host',
|
||||||
|
'share_type_id': 'fake_share_type_id',
|
||||||
|
}
|
||||||
|
fake_server = db_utils.create_share_server(
|
||||||
|
id='fake_srv_id', status=constants.STATUS_CREATING,
|
||||||
|
share_network_subnets=[share_net_subnet])
|
||||||
|
|
||||||
|
self.mock_object(self.share_manager, '_build_server_metadata',
|
||||||
|
mock.Mock(return_value=fake_metadata))
|
||||||
|
self.mock_object(db, 'share_server_create',
|
||||||
|
mock.Mock(return_value=fake_server))
|
||||||
|
self.mock_object(db, 'share_instance_update',
|
||||||
|
mock.Mock(return_value=fake_share.instance))
|
||||||
|
self.mock_object(db, 'share_instance_get',
|
||||||
|
mock.Mock(return_value=fake_share.instance))
|
||||||
|
self.mock_object(
|
||||||
|
db, 'share_network_subnets_get_all_by_availability_zone_id',
|
||||||
|
mock.Mock(return_value=[share_net_subnet]))
|
||||||
|
self.mock_object(manager.LOG, 'error')
|
||||||
|
|
||||||
|
def raise_manila_exception(*args, **kwargs):
|
||||||
|
raise exception.PortLimitExceeded()
|
||||||
|
|
||||||
|
self.mock_object(self.share_manager, '_setup_server',
|
||||||
|
mock.Mock(side_effect=raise_manila_exception))
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.PortLimitExceeded,
|
||||||
|
self.share_manager.create_share_instance,
|
||||||
|
self.context,
|
||||||
|
fake_share.instance['id'],
|
||||||
|
)
|
||||||
|
db.share_server_create.assert_called_once_with(
|
||||||
|
utils.IsAMatcher(context.RequestContext), mock.ANY)
|
||||||
|
db.share_instance_update.assert_has_calls([
|
||||||
|
mock.call(
|
||||||
|
utils.IsAMatcher(context.RequestContext),
|
||||||
|
fake_share.instance['id'],
|
||||||
|
{'status': constants.STATUS_ERROR},
|
||||||
|
)
|
||||||
|
])
|
||||||
|
self.share_manager._setup_server.assert_called_once_with(
|
||||||
|
utils.IsAMatcher(context.RequestContext), fake_server,
|
||||||
|
fake_metadata)
|
||||||
|
manager.LOG.error.assert_called_with(mock.ANY,
|
||||||
|
fake_share.instance['id'])
|
||||||
|
self.share_manager.message_api.create.assert_called_once_with(
|
||||||
|
utils.IsAMatcher(context.RequestContext),
|
||||||
|
message_field.Action.CREATE,
|
||||||
|
str(fake_share.project_id),
|
||||||
|
resource_type=message_field.Resource.SHARE,
|
||||||
|
resource_id=fake_share['id'],
|
||||||
|
detail=(
|
||||||
|
message_field.Detail.SHARE_NETWORK_PORT_QUOTA_LIMIT_EXCEEDED))
|
||||||
|
|
||||||
def test_create_share_instance_with_share_network_server_fail(self):
|
def test_create_share_instance_with_share_network_server_fail(self):
|
||||||
share_network = db_utils.create_share_network(id='fake_sn_id')
|
share_network = db_utils.create_share_network(id='fake_sn_id')
|
||||||
share_net_subnet = db_utils.create_share_network_subnet(
|
share_net_subnet = db_utils.create_share_network_subnet(
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
When share creation fails due to missing ports quota, error message
|
||||||
|
propogated to user is not useful. So reported PortLimitExceeded error to
|
||||||
|
user instead of generic error. For more details, please refer
|
||||||
|
(`launchpad bug 2019846 <https://bugs.launchpad.net/manila/+bug/2019846>`_).
|
Loading…
Reference in New Issue
Block a user