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 = (
|
||||
'026',
|
||||
_("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 = (
|
||||
UNKNOWN_ERROR,
|
||||
@ -169,6 +176,7 @@ class Detail(object):
|
||||
NO_DEFAULT_SHARE_TYPE,
|
||||
MISSING_SECURITY_SERVICE,
|
||||
DRIVER_FAILED_TRANSFER_ACCEPT,
|
||||
SHARE_NETWORK_PORT_QUOTA_LIMIT_EXCEEDED,
|
||||
)
|
||||
|
||||
# Exception and detail mappings
|
||||
|
@ -2048,6 +2048,23 @@ class ShareManager(manager.SchedulerDependentManager):
|
||||
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:
|
||||
with excutils.save_and_reraise_exception():
|
||||
error = ("Provision of share server failed: "
|
||||
|
@ -2163,6 +2163,69 @@ class ShareManagerTestCase(test.TestCase):
|
||||
share_id).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):
|
||||
share_network = db_utils.create_share_network(id='fake_sn_id')
|
||||
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