Merge "EMC VNX: Fix the interface garbage in VNX backend"

This commit is contained in:
Jenkins 2015-12-25 00:34:14 +00:00 committed by Gerrit Code Review
commit a921e2574a
4 changed files with 65 additions and 0 deletions

View File

@ -33,6 +33,7 @@ MSG_SNAP_EXIST = '13690535947'
MSG_INTERFACE_NAME_EXIST = '13421840550'
MSG_INTERFACE_EXIST = '13691781136'
MSG_INTERFACE_INVALID_VLAN_ID = '13421850371'
MSG_INTERFACE_NON_EXISTENT = '13691781134'
MSG_JOIN_DOMAIN = '13157007726'

View File

@ -1187,6 +1187,19 @@ class MoverInterface(StorageObject):
LOG.warn(_LW("Mover interface IP %s already exists. "
"Skip the creation."), ip_addr)
return
elif self._response_validation(
response, constants.MSG_INTERFACE_INVALID_VLAN_ID):
# When fail to create a mover interface with the specified
# vlan id, VNX will leave a interface with vlan id 0 in the
# backend. So we should explicitly remove the interface.
try:
self.delete(six.text_type(ip_addr), mover_name)
except exception.EMCVnxXMLAPIError:
pass
message = (_("Invalid vlan id %s. Other interfaces on this "
"subnet are in a different vlan.") % vlan_id)
LOG.error(message)
raise exception.EMCVnxXMLAPIError(err=message)
elif constants.STATUS_OK != response['maxSeverity']:
message = (_("Failed to create mover interface %(interface)s. "
"Reason: %(err)s.") %

View File

@ -940,6 +940,25 @@ class MoverTestData(StorageObjectTestData):
'</Status>' % {'ip': self.ip_address1}
)
@response
def resp_create_interface_with_conflicted_vlan_id(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13421850371" component="CS_CORE" '
'message="160: Invalid VLAN change. Other interfaces on this '
'subnet are in a different VLAN." severity="error">'
'<Description>The operation cannot complete because other '
'interfaces on the same subnet are in a different VLAN. '
'The Data Mover requires all interfaces in the same subnet '
'to be in the same VLAN.</Description>'
'<Action>Specify a VLAN to match other interfaces in the same '
'subnet. To move multiple interfaces to a different VLAN, '
'first set the VLAN id on each interface to 0, '
'and then set their VLAN id\'s to the new VLAN number.</Action>'
'</Problem>'
'</Status>'
)
@start_task
def req_delete_interface(self, ip=FakeData.network_allocations_ip1):

View File

@ -15,6 +15,7 @@
import copy
import ddt
import mock
from oslo_concurrency import processutils
@ -1520,6 +1521,7 @@ class SnapshotTestCase(StorageObjectTestCase):
context.conn['XML'].request.assert_has_calls(expected_calls)
@ddt.ddt
class MoverInterfaceTestCase(StorageObjectTestCase):
def setUp(self):
super(self.__class__, self).setUp()
@ -1602,6 +1604,36 @@ class MoverInterfaceTestCase(StorageObjectTestCase):
]
context.conn['XML'].request.assert_has_calls(expected_calls)
@ddt.data(fakes.MoverTestData().resp_task_succeed(),
fakes.MoverTestData().resp_task_error())
def test_create_mover_interface_with_conflict_vlan_id(self, xml_resp):
self.hook.append(self.mover.resp_get_ref_succeed())
self.hook.append(
self.mover.resp_create_interface_with_conflicted_vlan_id())
self.hook.append(xml_resp)
context = self.manager.getStorageContext('MoverInterface')
context.conn['XML'].request = utils.EMCMock(side_effect=self.hook)
interface = {
'name': self.mover.interface_name1,
'device_name': self.mover.device_name,
'ip': self.mover.ip_address1,
'mover_name': self.mover.mover_name,
'net_mask': self.mover.net_mask,
'vlan_id': self.mover.vlan_id,
}
self.assertRaises(exception.EMCVnxXMLAPIError,
context.create,
interface)
expected_calls = [
mock.call(self.mover.req_get_ref()),
mock.call(self.mover.req_create_interface()),
mock.call(self.mover.req_delete_interface()),
]
context.conn['XML'].request.assert_has_calls(expected_calls)
@mock.patch('time.sleep')
def test_create_mover_interface_invalid_mover_id(self, sleep_mock):
self.hook.append(self.mover.resp_get_ref_succeed())