Merge "Admin networks in NetApp cDOT multi-SVM driver"
This commit is contained in:
commit
4ad58d51ea
|
@ -416,8 +416,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
|||
|
||||
@na_utils.trace
|
||||
def create_network_interface(self, ip, netmask, vlan, node, port,
|
||||
vserver_name, allocation_id,
|
||||
lif_name_template, ipspace_name):
|
||||
vserver_name, lif_name, ipspace_name):
|
||||
"""Creates LIF on VLAN port."""
|
||||
|
||||
home_port_name = port
|
||||
|
@ -429,11 +428,8 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
|||
self._ensure_broadcast_domain_for_port(node, home_port_name,
|
||||
ipspace=ipspace_name)
|
||||
|
||||
interface_name = (lif_name_template %
|
||||
{'node': node, 'net_allocation_id': allocation_id})
|
||||
|
||||
LOG.debug('Creating LIF %(lif)s for Vserver %(vserver)s ',
|
||||
{'lif': interface_name, 'vserver': vserver_name})
|
||||
{'lif': lif_name, 'vserver': vserver_name})
|
||||
|
||||
api_args = {
|
||||
'address': ip,
|
||||
|
@ -445,7 +441,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
|||
'home-node': node,
|
||||
'home-port': home_port_name,
|
||||
'netmask': netmask,
|
||||
'interface-name': interface_name,
|
||||
'interface-name': lif_name,
|
||||
'role': 'data',
|
||||
'vserver': vserver_name,
|
||||
}
|
||||
|
|
|
@ -109,6 +109,10 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
|
|||
def get_network_allocations_number(self):
|
||||
return self.library.get_network_allocations_number()
|
||||
|
||||
def get_admin_network_allocations_number(self):
|
||||
return self.library.get_admin_network_allocations_number(
|
||||
self.admin_network_api)
|
||||
|
||||
def _setup_server(self, network_info, metadata=None):
|
||||
return self.library.setup_server(network_info, metadata)
|
||||
|
||||
|
|
|
@ -109,6 +109,9 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
|
|||
def get_network_allocations_number(self):
|
||||
return self.library.get_network_allocations_number()
|
||||
|
||||
def get_admin_network_allocations_number(self):
|
||||
return self.library.get_admin_network_allocations_number()
|
||||
|
||||
def _setup_server(self, network_info, metadata=None):
|
||||
return self.library.setup_server(network_info, metadata)
|
||||
|
||||
|
|
|
@ -353,7 +353,8 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
"""Creates new share."""
|
||||
vserver, vserver_client = self._get_vserver(share_server=share_server)
|
||||
self._allocate_container(share, vserver_client)
|
||||
return self._create_export(share, vserver, vserver_client)
|
||||
return self._create_export(share, share_server, vserver,
|
||||
vserver_client)
|
||||
|
||||
@na_utils.trace
|
||||
def create_share_from_snapshot(self, context, share, snapshot,
|
||||
|
@ -361,7 +362,8 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
"""Creates new share from snapshot."""
|
||||
vserver, vserver_client = self._get_vserver(share_server=share_server)
|
||||
self._allocate_container_from_snapshot(share, snapshot, vserver_client)
|
||||
return self._create_export(share, vserver, vserver_client)
|
||||
return self._create_export(share, share_server, vserver,
|
||||
vserver_client)
|
||||
|
||||
@na_utils.trace
|
||||
def _allocate_container(self, share, vserver_client):
|
||||
|
@ -584,7 +586,7 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
vserver_client.delete_volume(share_name)
|
||||
|
||||
@na_utils.trace
|
||||
def _create_export(self, share, vserver, vserver_client):
|
||||
def _create_export(self, share, share_server, vserver, vserver_client):
|
||||
"""Creates NAS storage."""
|
||||
helper = self._get_helper(share)
|
||||
helper.set_client(vserver_client)
|
||||
|
@ -600,8 +602,9 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
raise exception.NetAppException(msg % msg_args)
|
||||
|
||||
# Get LIF addresses with metadata
|
||||
export_addresses = self._get_export_addresses_with_metadata(share,
|
||||
interfaces)
|
||||
export_addresses = self._get_export_addresses_with_metadata(
|
||||
share, share_server, interfaces)
|
||||
|
||||
# Create the share and get a callback for generating export locations
|
||||
callback = helper.create_share(share, share_name)
|
||||
|
||||
|
@ -623,17 +626,23 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
return export_locations
|
||||
|
||||
@na_utils.trace
|
||||
def _get_export_addresses_with_metadata(self, share, interfaces):
|
||||
def _get_export_addresses_with_metadata(self, share, share_server,
|
||||
interfaces):
|
||||
"""Return interface addresses with locality and other metadata."""
|
||||
|
||||
# Get home node so we can identify preferred paths
|
||||
aggregate_name = share_utils.extract_host(share['host'], level='pool')
|
||||
home_node = self._get_aggregate_node(aggregate_name)
|
||||
|
||||
# Get admin LIF addresses so we can identify admin export locations
|
||||
admin_addresses = self._get_admin_addresses_for_share_server(
|
||||
share_server)
|
||||
|
||||
addresses = {}
|
||||
for interface in interfaces:
|
||||
|
||||
address = interface['address']
|
||||
is_admin_only = False
|
||||
is_admin_only = address in admin_addresses
|
||||
|
||||
if home_node:
|
||||
preferred = interface.get('home-node') == home_node
|
||||
|
@ -647,6 +656,19 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
|
||||
return addresses
|
||||
|
||||
@na_utils.trace
|
||||
def _get_admin_addresses_for_share_server(self, share_server):
|
||||
|
||||
if not share_server:
|
||||
return []
|
||||
|
||||
admin_addresses = []
|
||||
for network_allocation in share_server.get('network_allocations'):
|
||||
if network_allocation['label'] == 'admin':
|
||||
admin_addresses.append(network_allocation['ip_address'])
|
||||
|
||||
return admin_addresses
|
||||
|
||||
@na_utils.trace
|
||||
def _sort_export_locations_by_preferred_paths(self, export_locations):
|
||||
"""Sort the export locations to report preferred paths first."""
|
||||
|
@ -741,7 +763,8 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
def manage_existing(self, share, driver_options):
|
||||
vserver, vserver_client = self._get_vserver(share_server=None)
|
||||
share_size = self._manage_container(share, vserver_client)
|
||||
export_locations = self._create_export(share, vserver, vserver_client)
|
||||
export_locations = self._create_export(share, None, vserver,
|
||||
vserver_client)
|
||||
return {'size': share_size, 'export_locations': export_locations}
|
||||
|
||||
@na_utils.trace
|
||||
|
@ -866,6 +889,7 @@ class NetAppCmodeFileStorageLibrary(object):
|
|||
NetAppCmodeFileStorageLibrary._get_valid_cg_snapshot_name)
|
||||
|
||||
export_locations = self._create_export(clone['share'],
|
||||
share_server,
|
||||
vserver,
|
||||
vserver_client)
|
||||
share_update_list.append({
|
||||
|
|
|
@ -26,7 +26,7 @@ from oslo_log import log
|
|||
from oslo_utils import excutils
|
||||
|
||||
from manila import exception
|
||||
from manila.i18n import _, _LE, _LW
|
||||
from manila.i18n import _, _LE, _LW, _LI
|
||||
from manila.share.drivers.netapp.dataontap.client import client_cmode
|
||||
from manila.share.drivers.netapp.dataontap.cluster_mode import lib_base
|
||||
from manila.share.drivers.netapp import utils as na_utils
|
||||
|
@ -159,6 +159,11 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
|||
network_info,
|
||||
ipspace_name)
|
||||
|
||||
self._create_vserver_admin_lif(vserver_name,
|
||||
vserver_client,
|
||||
network_info,
|
||||
ipspace_name)
|
||||
|
||||
vserver_client.enable_nfs()
|
||||
|
||||
security_services = network_info.get('security_services')
|
||||
|
@ -183,7 +188,8 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
|||
if not self._client.features.IPSPACES:
|
||||
return None
|
||||
|
||||
if network_info['network_type'] not in SEGMENTED_NETWORK_TYPES:
|
||||
if (network_info['network_allocations'][0]['network_type']
|
||||
not in SEGMENTED_NETWORK_TYPES):
|
||||
return client_cmode.DEFAULT_IPSPACE
|
||||
|
||||
# NOTE(cknight): Neutron needs cDOT IP spaces because it can provide
|
||||
|
@ -200,26 +206,35 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
|||
return ipspace_name
|
||||
|
||||
@na_utils.trace
|
||||
def _create_vserver_lifs(self, vserver_name, vserver_client,
|
||||
network_info, ipspace_name):
|
||||
def _create_vserver_lifs(self, vserver_name, vserver_client, network_info,
|
||||
ipspace_name):
|
||||
"""Create Vserver data logical interfaces (LIFs)."""
|
||||
|
||||
nodes = self._client.list_cluster_nodes()
|
||||
node_network_info = zip(nodes, network_info['network_allocations'])
|
||||
netmask = utils.cidr_to_netmask(network_info['cidr'])
|
||||
|
||||
for node, net_info in node_network_info:
|
||||
net_id = net_info['id']
|
||||
port = self._get_node_data_port(node)
|
||||
ip = net_info['ip_address']
|
||||
self._create_lif_if_nonexistent(vserver_name,
|
||||
net_id,
|
||||
network_info['segmentation_id'],
|
||||
node,
|
||||
port,
|
||||
ip,
|
||||
netmask,
|
||||
ipspace_name,
|
||||
vserver_client)
|
||||
for node_name, network_allocation in node_network_info:
|
||||
lif_name = self._get_lif_name(node_name, network_allocation)
|
||||
self._create_lif(vserver_client, vserver_name, ipspace_name,
|
||||
node_name, lif_name, network_allocation)
|
||||
|
||||
@na_utils.trace
|
||||
def _create_vserver_admin_lif(self, vserver_name, vserver_client,
|
||||
network_info, ipspace_name):
|
||||
"""Create Vserver admin LIF, if defined."""
|
||||
|
||||
network_allocations = network_info.get('admin_network_allocations')
|
||||
if not network_allocations:
|
||||
LOG.info(_LI('No admin network defined for Vserver %s.') %
|
||||
vserver_name)
|
||||
return
|
||||
|
||||
node_name = self._client.list_cluster_nodes()[0]
|
||||
network_allocation = network_allocations[0]
|
||||
lif_name = self._get_lif_name(node_name, network_allocation)
|
||||
|
||||
self._create_lif(vserver_client, vserver_name, ipspace_name,
|
||||
node_name, lif_name, network_allocation)
|
||||
|
||||
@na_utils.trace
|
||||
def _get_node_data_port(self, node):
|
||||
|
@ -233,23 +248,41 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
|||
'to create Vserver LIFs.') % node)
|
||||
return matched_port_names[0]
|
||||
|
||||
def _get_lif_name(self, node_name, network_allocation):
|
||||
"""Get LIF name based on template from manila.conf file."""
|
||||
lif_name_args = {
|
||||
'node': node_name,
|
||||
'net_allocation_id': network_allocation['id'],
|
||||
}
|
||||
return self.configuration.netapp_lif_name_template % lif_name_args
|
||||
|
||||
@na_utils.trace
|
||||
def _create_lif_if_nonexistent(self, vserver_name, allocation_id, vlan,
|
||||
node, port, ip, netmask, ipspace_name,
|
||||
vserver_client):
|
||||
def _create_lif(self, vserver_client, vserver_name, ipspace_name,
|
||||
node_name, lif_name, network_allocation):
|
||||
"""Creates LIF for Vserver."""
|
||||
if not vserver_client.network_interface_exists(vserver_name, node,
|
||||
port, ip, netmask,
|
||||
vlan):
|
||||
|
||||
port = self._get_node_data_port(node_name)
|
||||
ip_address = network_allocation['ip_address']
|
||||
netmask = utils.cidr_to_netmask(network_allocation['cidr'])
|
||||
vlan = network_allocation['segmentation_id']
|
||||
|
||||
if not vserver_client.network_interface_exists(
|
||||
vserver_name, node_name, port, ip_address, netmask, vlan):
|
||||
|
||||
self._client.create_network_interface(
|
||||
ip, netmask, vlan, node, port, vserver_name, allocation_id,
|
||||
self.configuration.netapp_lif_name_template, ipspace_name)
|
||||
ip_address, netmask, vlan, node_name, port, vserver_name,
|
||||
lif_name, ipspace_name)
|
||||
|
||||
@na_utils.trace
|
||||
def get_network_allocations_number(self):
|
||||
"""Get number of network interfaces to be created."""
|
||||
return len(self._client.list_cluster_nodes())
|
||||
|
||||
@na_utils.trace
|
||||
def get_admin_network_allocations_number(self, admin_network_api):
|
||||
"""Get number of network allocations for creating admin LIFs."""
|
||||
return 1 if admin_network_api else 0
|
||||
|
||||
@na_utils.trace
|
||||
def teardown_server(self, server_details, security_services=None):
|
||||
"""Teardown share server."""
|
||||
|
|
|
@ -122,3 +122,8 @@ class NetAppCmodeSingleSVMFileStorageLibrary(
|
|||
def get_network_allocations_number(self):
|
||||
"""Get number of network interfaces to be created."""
|
||||
return 0
|
||||
|
||||
@na_utils.trace
|
||||
def get_admin_network_allocations_number(self):
|
||||
"""Get number of network allocations for creating admin LIFs."""
|
||||
return 0
|
||||
|
|
|
@ -739,12 +739,13 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
|||
'role': 'data',
|
||||
'vserver': fake.VSERVER_NAME,
|
||||
}
|
||||
self.client.create_network_interface(fake.IP_ADDRESS, fake.NETMASK,
|
||||
self.client.create_network_interface(fake.IP_ADDRESS,
|
||||
fake.NETMASK,
|
||||
fake.VLAN if use_vlans else None,
|
||||
fake.NODE_NAME, fake.PORT,
|
||||
fake.NODE_NAME,
|
||||
fake.PORT,
|
||||
fake.VSERVER_NAME,
|
||||
fake.NET_ALLOCATION_ID,
|
||||
fake.LIF_NAME_TEMPLATE,
|
||||
fake.LIF_NAME,
|
||||
fake.IPSPACE_NAME)
|
||||
|
||||
if use_vlans:
|
||||
|
|
|
@ -513,6 +513,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
mock_allocate_container.assert_called_once_with(fake.SHARE,
|
||||
vserver_client)
|
||||
mock_create_export.assert_called_once_with(fake.SHARE,
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client)
|
||||
self.assertEqual('fake_export_location', result)
|
||||
|
@ -543,6 +544,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
fake.SNAPSHOT,
|
||||
vserver_client)
|
||||
mock_create_export.assert_called_once_with(fake.SHARE,
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client)
|
||||
self.assertEqual('fake_export_location', result)
|
||||
|
@ -917,12 +919,13 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
mock.Mock(return_value=fake_interface_addresses_with_metadata))
|
||||
|
||||
result = self.library._create_export(fake.SHARE,
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client)
|
||||
|
||||
self.assertEqual(fake.NFS_EXPORTS, result)
|
||||
mock_get_export_addresses_with_metadata.assert_called_once_with(
|
||||
fake.SHARE, fake.LIFS)
|
||||
fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
|
||||
protocol_helper.create_share.assert_called_once_with(
|
||||
fake.SHARE, fake.SHARE_NAME)
|
||||
|
||||
|
@ -935,6 +938,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
self.assertRaises(exception.NetAppException,
|
||||
self.library._create_export,
|
||||
fake.SHARE,
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client)
|
||||
|
||||
|
@ -943,21 +947,29 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
mock_get_aggregate_node = self.mock_object(
|
||||
self.library, '_get_aggregate_node',
|
||||
mock.Mock(return_value=fake.CLUSTER_NODES[0]))
|
||||
mock_get_admin_addresses_for_share_server = self.mock_object(
|
||||
self.library, '_get_admin_addresses_for_share_server',
|
||||
mock.Mock(return_value=[fake.LIF_ADDRESSES[1]]))
|
||||
|
||||
result = self.library._get_export_addresses_with_metadata(
|
||||
fake.SHARE, fake.LIFS)
|
||||
fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
|
||||
|
||||
self.assertEqual(fake.INTERFACE_ADDRESSES_WITH_METADATA, result)
|
||||
mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
|
||||
mock_get_admin_addresses_for_share_server.assert_called_once_with(
|
||||
fake.SHARE_SERVER)
|
||||
|
||||
def test_get_export_addresses_with_metadata_node_unknown(self):
|
||||
|
||||
mock_get_aggregate_node = self.mock_object(
|
||||
self.library, '_get_aggregate_node',
|
||||
mock.Mock(return_value=None))
|
||||
mock_get_admin_addresses_for_share_server = self.mock_object(
|
||||
self.library, '_get_admin_addresses_for_share_server',
|
||||
mock.Mock(return_value=[fake.LIF_ADDRESSES[1]]))
|
||||
|
||||
result = self.library._get_export_addresses_with_metadata(
|
||||
fake.SHARE, fake.LIFS)
|
||||
fake.SHARE, fake.SHARE_SERVER, fake.LIFS)
|
||||
|
||||
expected = copy.deepcopy(fake.INTERFACE_ADDRESSES_WITH_METADATA)
|
||||
for key, value in expected.items():
|
||||
|
@ -965,6 +977,22 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
|
||||
self.assertEqual(expected, result)
|
||||
mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
|
||||
mock_get_admin_addresses_for_share_server.assert_called_once_with(
|
||||
fake.SHARE_SERVER)
|
||||
|
||||
def test_get_admin_addresses_for_share_server(self):
|
||||
|
||||
result = self.library._get_admin_addresses_for_share_server(
|
||||
fake.SHARE_SERVER)
|
||||
|
||||
self.assertEqual([fake.ADMIN_NETWORK_ALLOCATIONS[0]['ip_address']],
|
||||
result)
|
||||
|
||||
def test_get_admin_addresses_for_share_server_no_share_server(self):
|
||||
|
||||
result = self.library._get_admin_addresses_for_share_server(None)
|
||||
|
||||
self.assertEqual([], result)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_sort_export_locations_by_preferred_paths(self, reverse):
|
||||
|
@ -1208,6 +1236,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
mock_manage_container.assert_called_once_with(fake.SHARE,
|
||||
vserver_client)
|
||||
mock_create_export.assert_called_once_with(fake.SHARE,
|
||||
None,
|
||||
fake.VSERVER1,
|
||||
vserver_client)
|
||||
self.assertDictEqual(expected, result)
|
||||
|
@ -1479,9 +1508,11 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
])
|
||||
mock_create_export.assert_has_calls([
|
||||
mock.call(fake.COLLATED_CGSNAPSHOT_INFO[0]['share'],
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client),
|
||||
mock.call(fake.COLLATED_CGSNAPSHOT_INFO[1]['share'],
|
||||
fake.SHARE_SERVER,
|
||||
fake.VSERVER1,
|
||||
vserver_client),
|
||||
])
|
||||
|
|
|
@ -290,6 +290,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
'_create_ipspace',
|
||||
mock.Mock(return_value=fake.IPSPACE))
|
||||
self.mock_object(self.library, '_create_vserver_lifs')
|
||||
self.mock_object(self.library, '_create_vserver_admin_lif')
|
||||
|
||||
self.library._create_vserver(vserver_name, fake.NETWORK_INFO)
|
||||
|
||||
|
@ -300,6 +301,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
self.library._get_api_client.assert_called_with(vserver=vserver_name)
|
||||
self.library._create_vserver_lifs.assert_called_with(
|
||||
vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE)
|
||||
self.library._create_vserver_admin_lif.assert_called_with(
|
||||
vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE)
|
||||
self.assertTrue(vserver_client.enable_nfs.called)
|
||||
self.library._client.setup_security_services.assert_called_with(
|
||||
fake.NETWORK_INFO['security_services'], vserver_client,
|
||||
|
@ -387,8 +390,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
|
||||
self.library._client.features.IPSPACES = True
|
||||
network_info = copy.deepcopy(fake.NETWORK_INFO)
|
||||
network_info['segmentation_id'] = None
|
||||
network_info['network_type'] = network_type
|
||||
network_info['network_allocations'][0]['segmentation_id'] = None
|
||||
network_info['network_allocations'][0]['network_type'] = network_type
|
||||
|
||||
result = self.library._create_ipspace(network_info)
|
||||
|
||||
|
@ -444,36 +447,62 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
'list_cluster_nodes',
|
||||
mock.Mock(return_value=fake.CLUSTER_NODES))
|
||||
self.mock_object(self.library,
|
||||
'_get_node_data_port',
|
||||
mock.Mock(return_value=fake.NODE_DATA_PORT))
|
||||
self.mock_object(self.library, '_create_lif_if_nonexistent')
|
||||
'_get_lif_name',
|
||||
mock.Mock(side_effect=['fake_lif1', 'fake_lif2']))
|
||||
self.mock_object(self.library, '_create_lif')
|
||||
|
||||
self.library._create_vserver_lifs(fake.VSERVER1,
|
||||
'fake_vserver_client',
|
||||
fake.NETWORK_INFO,
|
||||
fake.IPSPACE)
|
||||
|
||||
self.library._create_lif_if_nonexistent.assert_has_calls([
|
||||
mock.call(
|
||||
fake.VSERVER1,
|
||||
fake.NETWORK_INFO['network_allocations'][0]['id'],
|
||||
fake.NETWORK_INFO['segmentation_id'],
|
||||
fake.CLUSTER_NODES[0],
|
||||
fake.NODE_DATA_PORT,
|
||||
fake.NETWORK_INFO['network_allocations'][0]['ip_address'],
|
||||
fake.NETWORK_INFO_NETMASK,
|
||||
fake.IPSPACE,
|
||||
'fake_vserver_client'),
|
||||
mock.call(
|
||||
fake.VSERVER1,
|
||||
fake.NETWORK_INFO['network_allocations'][1]['id'],
|
||||
fake.NETWORK_INFO['segmentation_id'],
|
||||
fake.CLUSTER_NODES[1],
|
||||
fake.NODE_DATA_PORT,
|
||||
fake.NETWORK_INFO['network_allocations'][1]['ip_address'],
|
||||
fake.NETWORK_INFO_NETMASK,
|
||||
fake.IPSPACE,
|
||||
'fake_vserver_client')])
|
||||
self.library._create_lif.assert_has_calls([
|
||||
mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE,
|
||||
fake.CLUSTER_NODES[0], 'fake_lif1',
|
||||
fake.NETWORK_INFO['network_allocations'][0]),
|
||||
mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE,
|
||||
fake.CLUSTER_NODES[1], 'fake_lif2',
|
||||
fake.NETWORK_INFO['network_allocations'][1])])
|
||||
|
||||
def test_create_vserver_admin_lif(self):
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
'list_cluster_nodes',
|
||||
mock.Mock(return_value=fake.CLUSTER_NODES))
|
||||
self.mock_object(self.library,
|
||||
'_get_lif_name',
|
||||
mock.Mock(return_value='fake_admin_lif'))
|
||||
self.mock_object(self.library, '_create_lif')
|
||||
|
||||
self.library._create_vserver_admin_lif(fake.VSERVER1,
|
||||
'fake_vserver_client',
|
||||
fake.NETWORK_INFO,
|
||||
fake.IPSPACE)
|
||||
|
||||
self.library._create_lif.assert_has_calls([
|
||||
mock.call('fake_vserver_client', fake.VSERVER1, fake.IPSPACE,
|
||||
fake.CLUSTER_NODES[0], 'fake_admin_lif',
|
||||
fake.NETWORK_INFO['admin_network_allocations'][0])])
|
||||
|
||||
def test_create_vserver_admin_lif_no_admin_network(self):
|
||||
|
||||
fake_network_info = copy.deepcopy(fake.NETWORK_INFO)
|
||||
fake_network_info['admin_network_allocations'] = []
|
||||
|
||||
self.mock_object(self.library._client,
|
||||
'list_cluster_nodes',
|
||||
mock.Mock(return_value=fake.CLUSTER_NODES))
|
||||
self.mock_object(self.library,
|
||||
'_get_lif_name',
|
||||
mock.Mock(return_value='fake_admin_lif'))
|
||||
self.mock_object(self.library, '_create_lif')
|
||||
|
||||
self.library._create_vserver_admin_lif(fake.VSERVER1,
|
||||
'fake_vserver_client',
|
||||
fake_network_info,
|
||||
fake.IPSPACE)
|
||||
|
||||
self.assertFalse(self.library._create_lif.called)
|
||||
|
||||
def test_get_node_data_port(self):
|
||||
|
||||
|
@ -499,49 +528,49 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
self.library._get_node_data_port,
|
||||
fake.CLUSTER_NODE)
|
||||
|
||||
def test_create_lif_if_nonexistent(self):
|
||||
def test_get_lif_name(self):
|
||||
|
||||
result = self.library._get_lif_name(
|
||||
'fake_node', fake.NETWORK_INFO['network_allocations'][0])
|
||||
|
||||
self.assertEqual('os_132dbb10-9a36-46f2-8d89-3d909830c356', result)
|
||||
|
||||
def test_create_lif(self):
|
||||
|
||||
vserver_client = mock.Mock()
|
||||
vserver_client.network_interface_exists = mock.Mock(
|
||||
return_value=False)
|
||||
self.mock_object(self.library,
|
||||
'_get_node_data_port',
|
||||
mock.Mock(return_value='fake_port'))
|
||||
|
||||
self.library._create_lif_if_nonexistent('fake_vserver',
|
||||
'fake_allocation_id',
|
||||
'fake_vlan',
|
||||
'fake_node',
|
||||
'fake_port',
|
||||
'fake_ip',
|
||||
'fake_netmask',
|
||||
fake.IPSPACE,
|
||||
vserver_client)
|
||||
self.library._create_lif(vserver_client,
|
||||
'fake_vserver',
|
||||
'fake_ipspace',
|
||||
'fake_node',
|
||||
'fake_lif',
|
||||
fake.NETWORK_INFO['network_allocations'][0])
|
||||
|
||||
self.library._client.create_network_interface.assert_has_calls([
|
||||
mock.call(
|
||||
'fake_ip',
|
||||
'fake_netmask',
|
||||
'fake_vlan',
|
||||
'fake_node',
|
||||
'fake_port',
|
||||
'fake_vserver',
|
||||
'fake_allocation_id',
|
||||
fake.LIF_NAME_TEMPLATE,
|
||||
fake.IPSPACE)])
|
||||
mock.call('10.10.10.10', '255.255.255.0', '1000', 'fake_node',
|
||||
'fake_port', 'fake_vserver', 'fake_lif',
|
||||
'fake_ipspace')])
|
||||
|
||||
def test_create_lif_if_nonexistent_already_present(self):
|
||||
|
||||
vserver_client = mock.Mock()
|
||||
vserver_client.network_interface_exists = mock.Mock(
|
||||
return_value=True)
|
||||
self.mock_object(self.library,
|
||||
'_get_node_data_port',
|
||||
mock.Mock(return_value='fake_port'))
|
||||
|
||||
self.library._create_lif_if_nonexistent('fake_vserver',
|
||||
'fake_allocation_id',
|
||||
'fake_vlan',
|
||||
'fake_node',
|
||||
'fake_port',
|
||||
'fake_ip',
|
||||
'fake_netmask',
|
||||
fake.IPSPACE,
|
||||
vserver_client)
|
||||
self.library._create_lif(vserver_client,
|
||||
'fake_vserver',
|
||||
fake.IPSPACE,
|
||||
'fake_node',
|
||||
'fake_lif',
|
||||
fake.NETWORK_INFO['network_allocations'][0])
|
||||
|
||||
self.assertFalse(self.library._client.create_network_interface.called)
|
||||
|
||||
|
@ -554,6 +583,19 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
|
||||
self.assertEqual(len(fake.CLUSTER_NODES), result)
|
||||
|
||||
def test_get_admin_network_allocations_number(self):
|
||||
|
||||
result = self.library.get_admin_network_allocations_number(
|
||||
'fake_admin_network_api')
|
||||
|
||||
self.assertEqual(1, result)
|
||||
|
||||
def test_get_admin_network_allocations_number_no_admin_network(self):
|
||||
|
||||
result = self.library.get_admin_network_allocations_number(None)
|
||||
|
||||
self.assertEqual(0, result)
|
||||
|
||||
def test_teardown_server(self):
|
||||
|
||||
self.library._client.vserver_exists.return_value = True
|
||||
|
|
|
@ -179,3 +179,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
|||
|
||||
def test_get_network_allocations_number(self):
|
||||
self.assertEqual(0, self.library.get_network_allocations_number())
|
||||
|
||||
def test_get_admin_network_allocations_number(self):
|
||||
|
||||
result = self.library.get_admin_network_allocations_number()
|
||||
|
||||
self.assertEqual(0, result)
|
||||
|
|
|
@ -209,18 +209,41 @@ REMAPPED_OVERLAPPING_EXTRA_SPEC = {
|
|||
EXTRA_SPEC_SHARE = copy.deepcopy(SHARE)
|
||||
EXTRA_SPEC_SHARE['share_type_id'] = SHARE_TYPE_ID
|
||||
|
||||
USER_NETWORK_ALLOCATIONS = [
|
||||
{
|
||||
'id': '132dbb10-9a36-46f2-8d89-3d909830c356',
|
||||
'ip_address': '10.10.10.10',
|
||||
'cidr': '10.10.10.0/24',
|
||||
'segmentation_id': '1000',
|
||||
'network_type': 'vlan',
|
||||
'label': 'user',
|
||||
},
|
||||
{
|
||||
'id': '7eabdeed-bad2-46ea-bd0f-a33884c869e0',
|
||||
'ip_address': '10.10.10.20',
|
||||
'cidr': '10.10.10.0/24',
|
||||
'segmentation_id': '1000',
|
||||
'network_type': 'vlan',
|
||||
'label': 'user',
|
||||
}
|
||||
]
|
||||
|
||||
ADMIN_NETWORK_ALLOCATIONS = [
|
||||
{
|
||||
'id': '132dbb10-9a36-46f2-8d89-3d909830c356',
|
||||
'ip_address': '10.10.20.10',
|
||||
'cidr': '10.10.20.0/24',
|
||||
'segmentation_id': None,
|
||||
'network_type': 'flat',
|
||||
'label': 'admin',
|
||||
},
|
||||
]
|
||||
|
||||
NETWORK_INFO = {
|
||||
'server_id': '56aafd02-4d44-43d7-b784-57fc88167224',
|
||||
'cidr': '10.0.0.0/24',
|
||||
'security_services': ['fake_ldap', 'fake_kerberos', 'fake_ad', ],
|
||||
'segmentation_id': '1000',
|
||||
'network_type': 'vlan',
|
||||
'network_allocations': [
|
||||
{'id': '132dbb10-9a36-46f2-8d89-3d909830c356',
|
||||
'ip_address': '10.10.10.10'},
|
||||
{'id': '7eabdeed-bad2-46ea-bd0f-a33884c869e0',
|
||||
'ip_address': '10.10.10.20'}
|
||||
],
|
||||
'network_allocations': USER_NETWORK_ALLOCATIONS,
|
||||
'admin_network_allocations': ADMIN_NETWORK_ALLOCATIONS,
|
||||
'neutron_subnet_id': '62bf1c2c-18eb-421b-8983-48a6d39aafe0',
|
||||
}
|
||||
NETWORK_INFO_NETMASK = '255.255.255.0'
|
||||
|
@ -229,7 +252,9 @@ SHARE_SERVER = {
|
|||
'share_network_id': 'c5b3a865-56d0-4d88-abe5-879965e099c9',
|
||||
'backend_details': {
|
||||
'vserver_name': VSERVER1
|
||||
}
|
||||
},
|
||||
'network_allocations': (USER_NETWORK_ALLOCATIONS +
|
||||
ADMIN_NETWORK_ALLOCATIONS),
|
||||
}
|
||||
|
||||
SNAPSHOT = {
|
||||
|
@ -386,7 +411,7 @@ INTERFACE_ADDRESSES_WITH_METADATA = {
|
|||
'preferred': True,
|
||||
},
|
||||
LIF_ADDRESSES[1]: {
|
||||
'is_admin_only': False,
|
||||
'is_admin_only': True,
|
||||
'preferred': False,
|
||||
},
|
||||
}
|
||||
|
@ -401,7 +426,7 @@ NFS_EXPORTS = [
|
|||
},
|
||||
{
|
||||
'path': ':'.join([LIF_ADDRESSES[1], 'fake_export_path']),
|
||||
'is_admin_only': False,
|
||||
'is_admin_only': True,
|
||||
'metadata': {
|
||||
'preferred': False,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue