NetApp cDOT: Fix share server deletion
The DHSS=True cDOT driver can be used with non-segmented networks, and the driver should not assume that network interfaces are always assigned to VLAN ports. Change-Id: Ifffae0f5e42d16ea40d693116b720c7f7d57c971 Closes-Bug: #1698250
This commit is contained in:
parent
1cf5ccdbdd
commit
abe3224774
|
@ -332,12 +332,16 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||||
vserver_client = self._get_api_client(vserver=vserver)
|
vserver_client = self._get_api_client(vserver=vserver)
|
||||||
network_interfaces = vserver_client.get_network_interfaces()
|
network_interfaces = vserver_client.get_network_interfaces()
|
||||||
|
|
||||||
vlan = None
|
interfaces_on_vlans = []
|
||||||
if network_interfaces:
|
vlans = []
|
||||||
home_port = network_interfaces[0]['home-port']
|
for interface in network_interfaces:
|
||||||
vlan = home_port.split('-')[1]
|
if '-' in interface['home-port']:
|
||||||
|
interfaces_on_vlans.append(interface)
|
||||||
|
vlans.append(interface['home-port'])
|
||||||
|
|
||||||
@utils.synchronized('netapp-VLAN-%s' % vlan, external=True)
|
vlans = '-'.join(set(sorted(vlans))) if vlans else None
|
||||||
|
|
||||||
|
@utils.synchronized('netapp-VLANs-%s' % vlans, external=True)
|
||||||
def _delete_vserver_with_lock():
|
def _delete_vserver_with_lock():
|
||||||
self._client.delete_vserver(vserver,
|
self._client.delete_vserver(vserver,
|
||||||
vserver_client,
|
vserver_client,
|
||||||
|
@ -347,15 +351,15 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||||
ipspace_name):
|
ipspace_name):
|
||||||
self._client.delete_ipspace(ipspace_name)
|
self._client.delete_ipspace(ipspace_name)
|
||||||
|
|
||||||
self._delete_vserver_vlan(network_interfaces)
|
self._delete_vserver_vlans(interfaces_on_vlans)
|
||||||
|
|
||||||
return _delete_vserver_with_lock()
|
return _delete_vserver_with_lock()
|
||||||
|
|
||||||
@na_utils.trace
|
@na_utils.trace
|
||||||
def _delete_vserver_vlan(self, vserver_network_interfaces):
|
def _delete_vserver_vlans(self, network_interfaces_on_vlans):
|
||||||
"""Delete Vserver's VLAN configuration from ports"""
|
"""Delete Vserver's VLAN configuration from ports"""
|
||||||
|
|
||||||
for interface in vserver_network_interfaces:
|
for interface in network_interfaces_on_vlans:
|
||||||
try:
|
try:
|
||||||
home_port = interface['home-port']
|
home_port = interface['home-port']
|
||||||
port, vlan = home_port.split('-')
|
port, vlan = home_port.split('-')
|
||||||
|
|
|
@ -96,6 +96,27 @@ NETWORK_INTERFACES = [{
|
||||||
'home-port': VLAN_PORT
|
'home-port': VLAN_PORT
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
NETWORK_INTERFACES_MULTIPLE = [
|
||||||
|
{
|
||||||
|
'interface_name': 'fake_interface',
|
||||||
|
'address': IP_ADDRESS,
|
||||||
|
'vserver': VSERVER_NAME,
|
||||||
|
'netmask': NETMASK,
|
||||||
|
'role': 'data',
|
||||||
|
'home-node': NODE_NAME,
|
||||||
|
'home-port': VLAN_PORT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'interface_name': 'fake_interface_2',
|
||||||
|
'address': '10.10.12.10',
|
||||||
|
'vserver': VSERVER_NAME,
|
||||||
|
'netmask': NETMASK,
|
||||||
|
'role': 'data',
|
||||||
|
'home-node': NODE_NAME,
|
||||||
|
'home-port': PORT,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
IPSPACES = [{
|
IPSPACES = [{
|
||||||
'uuid': 'fake_uuid',
|
'uuid': 'fake_uuid',
|
||||||
'ipspace': IPSPACE_NAME,
|
'ipspace': IPSPACE_NAME,
|
||||||
|
|
|
@ -670,11 +670,15 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.mock_object(self.library,
|
self.mock_object(self.library,
|
||||||
'_get_api_client',
|
'_get_api_client',
|
||||||
mock.Mock(return_value=vserver_client))
|
mock.Mock(return_value=vserver_client))
|
||||||
mock_delete_vserver_vlan = self.mock_object(self.library,
|
mock_delete_vserver_vlans = self.mock_object(self.library,
|
||||||
'_delete_vserver_vlan')
|
'_delete_vserver_vlans')
|
||||||
|
|
||||||
|
net_interfaces = copy.deepcopy(c_fake.NETWORK_INTERFACES_MULTIPLE)
|
||||||
|
net_interfaces_with_vlans = [net_interfaces[0]]
|
||||||
|
|
||||||
self.mock_object(vserver_client,
|
self.mock_object(vserver_client,
|
||||||
'get_network_interfaces',
|
'get_network_interfaces',
|
||||||
mock.Mock(return_value=c_fake.NETWORK_INTERFACES))
|
mock.Mock(return_value=net_interfaces))
|
||||||
security_services = fake.NETWORK_INFO['security_services']
|
security_services = fake.NETWORK_INFO['security_services']
|
||||||
|
|
||||||
self.library._delete_vserver(fake.VSERVER1,
|
self.library._delete_vserver(fake.VSERVER1,
|
||||||
|
@ -685,8 +689,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.library._client.delete_vserver.assert_called_once_with(
|
self.library._client.delete_vserver.assert_called_once_with(
|
||||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||||
self.assertFalse(self.library._client.delete_ipspace.called)
|
self.assertFalse(self.library._client.delete_ipspace.called)
|
||||||
mock_delete_vserver_vlan.assert_called_once_with(
|
mock_delete_vserver_vlans.assert_called_once_with(
|
||||||
c_fake.NETWORK_INTERFACES)
|
net_interfaces_with_vlans)
|
||||||
|
|
||||||
def test_delete_vserver_ipspace_has_data_vservers(self):
|
def test_delete_vserver_ipspace_has_data_vservers(self):
|
||||||
|
|
||||||
|
@ -700,11 +704,11 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.mock_object(self.library._client,
|
self.mock_object(self.library._client,
|
||||||
'ipspace_has_data_vservers',
|
'ipspace_has_data_vservers',
|
||||||
mock.Mock(return_value=True))
|
mock.Mock(return_value=True))
|
||||||
mock_delete_vserver_vlan = self.mock_object(self.library,
|
mock_delete_vserver_vlans = self.mock_object(self.library,
|
||||||
'_delete_vserver_vlan')
|
'_delete_vserver_vlans')
|
||||||
self.mock_object(vserver_client,
|
self.mock_object(
|
||||||
'get_network_interfaces',
|
vserver_client, 'get_network_interfaces',
|
||||||
mock.Mock(return_value=c_fake.NETWORK_INTERFACES))
|
mock.Mock(return_value=c_fake.NETWORK_INTERFACES_MULTIPLE))
|
||||||
security_services = fake.NETWORK_INFO['security_services']
|
security_services = fake.NETWORK_INFO['security_services']
|
||||||
|
|
||||||
self.library._delete_vserver(fake.VSERVER1,
|
self.library._delete_vserver(fake.VSERVER1,
|
||||||
|
@ -715,8 +719,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.library._client.delete_vserver.assert_called_once_with(
|
self.library._client.delete_vserver.assert_called_once_with(
|
||||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||||
self.assertFalse(self.library._client.delete_ipspace.called)
|
self.assertFalse(self.library._client.delete_ipspace.called)
|
||||||
mock_delete_vserver_vlan.assert_called_once_with(
|
mock_delete_vserver_vlans.assert_called_once_with(
|
||||||
c_fake.NETWORK_INTERFACES)
|
[c_fake.NETWORK_INTERFACES_MULTIPLE[0]])
|
||||||
|
|
||||||
@ddt.data([], c_fake.NETWORK_INTERFACES)
|
@ddt.data([], c_fake.NETWORK_INTERFACES)
|
||||||
def test_delete_vserver_with_ipspace(self, interfaces):
|
def test_delete_vserver_with_ipspace(self, interfaces):
|
||||||
|
@ -731,8 +735,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.mock_object(self.library._client,
|
self.mock_object(self.library._client,
|
||||||
'ipspace_has_data_vservers',
|
'ipspace_has_data_vservers',
|
||||||
mock.Mock(return_value=False))
|
mock.Mock(return_value=False))
|
||||||
mock_delete_vserver_vlan = self.mock_object(self.library,
|
mock_delete_vserver_vlans = self.mock_object(self.library,
|
||||||
'_delete_vserver_vlan')
|
'_delete_vserver_vlans')
|
||||||
self.mock_object(vserver_client,
|
self.mock_object(vserver_client,
|
||||||
'get_network_interfaces',
|
'get_network_interfaces',
|
||||||
mock.Mock(return_value=interfaces))
|
mock.Mock(return_value=interfaces))
|
||||||
|
@ -748,11 +752,11 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
fake.VSERVER1, vserver_client, security_services=security_services)
|
fake.VSERVER1, vserver_client, security_services=security_services)
|
||||||
self.library._client.delete_ipspace.assert_called_once_with(
|
self.library._client.delete_ipspace.assert_called_once_with(
|
||||||
fake.IPSPACE)
|
fake.IPSPACE)
|
||||||
mock_delete_vserver_vlan.assert_called_once_with(interfaces)
|
mock_delete_vserver_vlans.assert_called_once_with(interfaces)
|
||||||
|
|
||||||
def test_delete_vserver_vlan(self):
|
def test_delete_vserver_vlans(self):
|
||||||
|
|
||||||
self.library._delete_vserver_vlan(c_fake.NETWORK_INTERFACES)
|
self.library._delete_vserver_vlans(c_fake.NETWORK_INTERFACES)
|
||||||
for interface in c_fake.NETWORK_INTERFACES:
|
for interface in c_fake.NETWORK_INTERFACES:
|
||||||
home_port = interface['home-port']
|
home_port = interface['home-port']
|
||||||
port, vlan = home_port.split('-')
|
port, vlan = home_port.split('-')
|
||||||
|
@ -760,7 +764,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
self.library._client.delete_vlan.assert_called_once_with(
|
self.library._client.delete_vlan.assert_called_once_with(
|
||||||
node, port, vlan)
|
node, port, vlan)
|
||||||
|
|
||||||
def test_delete_vserver_vlan_client_error(self):
|
def test_delete_vserver_vlans_client_error(self):
|
||||||
|
|
||||||
mock_exception_log = self.mock_object(lib_multi_svm.LOG, 'exception')
|
mock_exception_log = self.mock_object(lib_multi_svm.LOG, 'exception')
|
||||||
self.mock_object(
|
self.mock_object(
|
||||||
|
@ -768,7 +772,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||||
'delete_vlan',
|
'delete_vlan',
|
||||||
mock.Mock(side_effect=exception.NetAppException("fake error")))
|
mock.Mock(side_effect=exception.NetAppException("fake error")))
|
||||||
|
|
||||||
self.library._delete_vserver_vlan(c_fake.NETWORK_INTERFACES)
|
self.library._delete_vserver_vlans(c_fake.NETWORK_INTERFACES)
|
||||||
for interface in c_fake.NETWORK_INTERFACES:
|
for interface in c_fake.NETWORK_INTERFACES:
|
||||||
home_port = interface['home-port']
|
home_port = interface['home-port']
|
||||||
port, vlan = home_port.split('-')
|
port, vlan = home_port.split('-')
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- The NetApp cDOT DHSS=True drivers have been fixed to not assume that share
|
||||||
|
servers are only provisioned on segmented (VLAN) networks.
|
Loading…
Reference in New Issue