summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoutham Pacha Ravi <gouthampravi@gmail.com>2017-06-18 21:17:56 -0400
committerGoutham Pacha Ravi <gouthampravi@gmail.com>2018-08-01 04:49:27 +0000
commit546f3c84788bc0448c9afd0dea88c633c1555603 (patch)
treeeea4dd03f230c703372d2123d04eb333b4710f7d
parent6b14188ac6e2bd8d9f9084f3ef0463a62ed96af1 (diff)
NetApp cDOT: Add gateway information to create static routes
Add tenant routes/gateway to Vservers created by the driver. Change-Id: Id33c0e13d265d50f74f86ab8fb2c533eefa4b783 Closes-Bug: #1698258 Closes-Bug: #1612655 (cherry picked from commit f88df34e3188624ed60c69d9e159bfebe17b0f91) (cherry picked from commit 11c8145b964bf2eecc16b29bf20627b73805ff2c)
Notes
Notes (review): Code-Review+2: Tom Barron <tpb@dyncloud.net> Workflow+1: Tom Barron <tpb@dyncloud.net> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 02 Aug 2018 11:57:28 +0000 Reviewed-on: https://review.openstack.org/587685 Project: openstack/manila Branch: refs/heads/driverfixes/newton
-rw-r--r--manila/share/drivers/netapp/dataontap/client/client_cmode.py25
-rw-r--r--manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py18
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/client/fakes.py19
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py51
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py32
-rw-r--r--manila/tests/share/drivers/netapp/dataontap/fakes.py34
-rw-r--r--releasenotes/notes/bug-1698258-netapp-fix-tenant-network-gateways-85935582e89a72a0.yaml7
7 files changed, 179 insertions, 7 deletions
diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode.py b/manila/share/drivers/netapp/dataontap/client/client_cmode.py
index f92227c..49d5a58 100644
--- a/manila/share/drivers/netapp/dataontap/client/client_cmode.py
+++ b/manila/share/drivers/netapp/dataontap/client/client_cmode.py
@@ -553,6 +553,31 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
553 raise exception.NetAppException(msg % msg_args) 553 raise exception.NetAppException(msg % msg_args)
554 554
555 @na_utils.trace 555 @na_utils.trace
556 def create_route(self, gateway, destination='0.0.0.0/0'):
557 try:
558 api_args = {
559 'destination': destination,
560 'gateway': gateway,
561 'return-record': 'true',
562 }
563 self.send_request('net-routes-create', api_args)
564 except netapp_api.NaApiError as e:
565 p = re.compile('.*Duplicate route exists.*', re.IGNORECASE)
566 if (e.code == netapp_api.EAPIERROR and re.match(p, e.message)):
567 LOG.debug('Route to %(destination)s via gateway %(gateway)s '
568 'exists.',
569 {'destination': destination, 'gateway': gateway})
570 else:
571 msg = _('Failed to create a route to %(destination)s via '
572 'gateway %(gateway)s: %(err_msg)s')
573 msg_args = {
574 'destination': destination,
575 'gateway': gateway,
576 'err_msg': e.message,
577 }
578 raise exception.NetAppException(msg % msg_args)
579
580 @na_utils.trace
556 def _ensure_broadcast_domain_for_port(self, node, port, mtu, 581 def _ensure_broadcast_domain_for_port(self, node, port, mtu,
557 ipspace=DEFAULT_IPSPACE): 582 ipspace=DEFAULT_IPSPACE):
558 """Ensure a port is in a broadcast domain. Create one if necessary. 583 """Ensure a port is in a broadcast domain. Create one if necessary.
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
index 3219c57..ebf749e 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
@@ -173,6 +173,9 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
173 network_info, 173 network_info,
174 ipspace_name) 174 ipspace_name)
175 175
176 self._create_vserver_routes(vserver_client,
177 network_info)
178
176 vserver_client.enable_nfs( 179 vserver_client.enable_nfs(
177 self.configuration.netapp_enabled_share_protocols) 180 self.configuration.netapp_enabled_share_protocols)
178 181
@@ -247,6 +250,20 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
247 node_name, lif_name, network_allocation) 250 node_name, lif_name, network_allocation)
248 251
249 @na_utils.trace 252 @na_utils.trace
253 def _create_vserver_routes(self, vserver_client, network_info):
254 """Create Vserver route and set gateways."""
255 route_gateways = []
256 # NOTE(gouthamr): Use the gateway from the tenant subnet/s
257 # for the static routes. Do not configure a route for the admin
258 # subnet because fast path routing will work for incoming
259 # connections and there are no requirements for outgoing
260 # connections on the admin network yet.
261 for net_allocation in (network_info['network_allocations']):
262 if net_allocation['gateway'] not in route_gateways:
263 vserver_client.create_route(net_allocation['gateway'])
264 route_gateways.append(net_allocation['gateway'])
265
266 @na_utils.trace
250 def _get_node_data_port(self, node): 267 def _get_node_data_port(self, node):
251 port_names = self._client.list_node_data_ports(node) 268 port_names = self._client.list_node_data_ports(node)
252 pattern = self.configuration.netapp_port_name_search_pattern 269 pattern = self.configuration.netapp_port_name_search_pattern
@@ -350,7 +367,6 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
350 @na_utils.trace 367 @na_utils.trace
351 def _delete_vserver_vlans(self, network_interfaces_on_vlans): 368 def _delete_vserver_vlans(self, network_interfaces_on_vlans):
352 """Delete Vserver's VLAN configuration from ports""" 369 """Delete Vserver's VLAN configuration from ports"""
353
354 for interface in network_interfaces_on_vlans: 370 for interface in network_interfaces_on_vlans:
355 try: 371 try:
356 home_port = interface['home-port'] 372 home_port = interface['home-port']
diff --git a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
index a328a5f..8109332 100644
--- a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
+++ b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
@@ -73,6 +73,8 @@ VLAN = '1001'
73VLAN_PORT = 'e0a-1001' 73VLAN_PORT = 'e0a-1001'
74IP_ADDRESS = '10.10.10.10' 74IP_ADDRESS = '10.10.10.10'
75NETMASK = '255.255.255.0' 75NETMASK = '255.255.255.0'
76GATEWAY = '10.10.10.1'
77SUBNET = '10.10.10.0/24'
76NET_ALLOCATION_ID = 'fake_allocation_id' 78NET_ALLOCATION_ID = 'fake_allocation_id'
77LIF_NAME_TEMPLATE = 'os_%(net_allocation_id)s' 79LIF_NAME_TEMPLATE = 'os_%(net_allocation_id)s'
78LIF_NAME = LIF_NAME_TEMPLATE % {'net_allocation_id': NET_ALLOCATION_ID} 80LIF_NAME = LIF_NAME_TEMPLATE % {'net_allocation_id': NET_ALLOCATION_ID}
@@ -2079,6 +2081,23 @@ SNAPMIRROR_INITIALIZE_RESULT = etree.XML("""
2079 </results> 2081 </results>
2080""") 2082""")
2081 2083
2084NET_ROUTES_CREATE_RESPONSE = etree.XML("""
2085 <results status="passed">
2086 <result>
2087 <net-vs-routes-info>
2088 <address-family>ipv4</address-family>
2089 <destination>%(subnet)s</destination>
2090 <gateway>%(gateway)s</gateway>
2091 <metric>20</metric>
2092 <vserver>%(vserver)s</vserver>
2093 </net-vs-routes-info>
2094 </result>
2095 </results>""" % {
2096 'gateway': GATEWAY,
2097 'vserver': VSERVER_NAME,
2098 'subnet': SUBNET,
2099})
2100
2082FAKE_VOL_XML = """<volume-info xmlns='http://www.netapp.com/filer/admin'> 2101FAKE_VOL_XML = """<volume-info xmlns='http://www.netapp.com/filer/admin'>
2083 <name>open123</name> 2102 <name>open123</name>
2084 <state>online</state> 2103 <state>online</state>
diff --git a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
index d370bb5..90bd32c 100644
--- a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
+++ b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
@@ -981,6 +981,57 @@ class NetAppClientCmodeTestCase(test.TestCase):
981 fake.PORT, 981 fake.PORT,
982 fake.VLAN) 982 fake.VLAN)
983 983
984 def test_create_route(self):
985 api_response = netapp_api.NaElement(
986 fake.NET_ROUTES_CREATE_RESPONSE)
987 expected_api_args = {
988 'destination': fake.SUBNET,
989 'gateway': fake.GATEWAY,
990 'return-record': 'true',
991 }
992 self.mock_object(
993 self.client, 'send_request', mock.Mock(return_value=api_response))
994
995 self.client.create_route(fake.GATEWAY, destination=fake.SUBNET)
996
997 self.client.send_request.assert_called_once_with(
998 'net-routes-create', expected_api_args)
999
1000 def test_create_route_duplicate(self):
1001 self.mock_object(client_cmode.LOG, 'debug')
1002 expected_api_args = {
1003 'destination': fake.SUBNET,
1004 'gateway': fake.GATEWAY,
1005 'return-record': 'true',
1006 }
1007 self.mock_object(
1008 self.client, 'send_request',
1009 mock.Mock(side_effect=self._mock_api_error(
1010 code=netapp_api.EAPIERROR, message='Duplicate route exists.')))
1011
1012 self.client.create_route(fake.GATEWAY, destination=fake.SUBNET)
1013
1014 self.client.send_request.assert_called_once_with(
1015 'net-routes-create', expected_api_args)
1016 self.assertEqual(1, client_cmode.LOG.debug.call_count)
1017
1018 def test_create_route_api_error(self):
1019 expected_api_args = {
1020 'destination': fake.SUBNET,
1021 'gateway': fake.GATEWAY,
1022 'return-record': 'true',
1023 }
1024 self.mock_object(
1025 self.client, 'send_request',
1026 mock.Mock(side_effect=self._mock_api_error()))
1027
1028 self.assertRaises(exception.NetAppException,
1029 self.client.create_route,
1030 fake.GATEWAY, destination=fake.SUBNET)
1031
1032 self.client.send_request.assert_called_once_with(
1033 'net-routes-create', expected_api_args)
1034
984 def test_ensure_broadcast_domain_for_port_domain_match(self): 1035 def test_ensure_broadcast_domain_for_port_domain_match(self):
985 1036
986 port_info = { 1037 port_info = {
diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
index 9efa567..2b3f286 100644
--- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
+++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
@@ -296,20 +296,24 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
296 mock.Mock(return_value=fake.IPSPACE)) 296 mock.Mock(return_value=fake.IPSPACE))
297 self.mock_object(self.library, '_create_vserver_lifs') 297 self.mock_object(self.library, '_create_vserver_lifs')
298 self.mock_object(self.library, '_create_vserver_admin_lif') 298 self.mock_object(self.library, '_create_vserver_admin_lif')
299 self.mock_object(self.library, '_create_vserver_routes')
299 300
300 self.library._create_vserver(vserver_name, fake.NETWORK_INFO) 301 self.library._create_vserver(vserver_name, fake.NETWORK_INFO)
301 302
302 self.library._create_ipspace.assert_called_with(fake.NETWORK_INFO) 303 self.library._create_ipspace.assert_called_once_with(fake.NETWORK_INFO)
303 self.library._client.create_vserver.assert_called_with( 304 self.library._client.create_vserver.assert_called_once_with(
304 vserver_name, fake.ROOT_VOLUME_AGGREGATE, fake.ROOT_VOLUME, 305 vserver_name, fake.ROOT_VOLUME_AGGREGATE, fake.ROOT_VOLUME,
305 fake.AGGREGATES, fake.IPSPACE) 306 fake.AGGREGATES, fake.IPSPACE)
306 self.library._get_api_client.assert_called_with(vserver=vserver_name) 307 self.library._get_api_client.assert_called_once_with(
307 self.library._create_vserver_lifs.assert_called_with( 308 vserver=vserver_name)
309 self.library._create_vserver_lifs.assert_called_once_with(
308 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE) 310 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE)
309 self.library._create_vserver_admin_lif.assert_called_with( 311 self.library._create_vserver_admin_lif.assert_called_once_with(
310 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE) 312 vserver_name, vserver_client, fake.NETWORK_INFO, fake.IPSPACE)
313 self.library._create_vserver_routes.assert_called_once_with(
314 vserver_client, fake.NETWORK_INFO)
311 vserver_client.enable_nfs.assert_called_once_with(versions) 315 vserver_client.enable_nfs.assert_called_once_with(versions)
312 self.library._client.setup_security_services.assert_called_with( 316 self.library._client.setup_security_services.assert_called_once_with(
313 fake.NETWORK_INFO['security_services'], vserver_client, 317 fake.NETWORK_INFO['security_services'], vserver_client,
314 vserver_name) 318 vserver_name)
315 319
@@ -509,6 +513,22 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
509 513
510 self.assertFalse(self.library._create_lif.called) 514 self.assertFalse(self.library._create_lif.called)
511 515
516 @ddt.data(
517 fake.get_network_info(fake.USER_NETWORK_ALLOCATIONS,
518 fake.ADMIN_NETWORK_ALLOCATIONS),
519 fake.get_network_info(fake.USER_NETWORK_ALLOCATIONS_IPV6,
520 fake.ADMIN_NETWORK_ALLOCATIONS))
521 def test_create_vserver_routes(self, network_info):
522 expected_gateway = network_info['network_allocations'][0]['gateway']
523 vserver_client = mock.Mock()
524 self.mock_object(vserver_client, 'create_route')
525
526 retval = self.library._create_vserver_routes(
527 vserver_client, network_info)
528
529 self.assertIsNone(retval)
530 vserver_client.create_route.assert_called_once_with(expected_gateway)
531
512 def test_get_node_data_port(self): 532 def test_get_node_data_port(self):
513 533
514 self.mock_object(self.client, 534 self.mock_object(self.client,
diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py
index 766d834..4917ab5 100644
--- a/manila/tests/share/drivers/netapp/dataontap/fakes.py
+++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py
@@ -227,6 +227,7 @@ USER_NETWORK_ALLOCATIONS = [
227 'network_type': 'vlan', 227 'network_type': 'vlan',
228 'label': 'user', 228 'label': 'user',
229 'mtu': MTU, 229 'mtu': MTU,
230 'gateway': '10.10.10.1',
230 }, 231 },
231 { 232 {
232 'id': '7eabdeed-bad2-46ea-bd0f-a33884c869e0', 233 'id': '7eabdeed-bad2-46ea-bd0f-a33884c869e0',
@@ -236,6 +237,30 @@ USER_NETWORK_ALLOCATIONS = [
236 'network_type': 'vlan', 237 'network_type': 'vlan',
237 'label': 'user', 238 'label': 'user',
238 'mtu': MTU, 239 'mtu': MTU,
240 'gateway': '10.10.10.1',
241 }
242]
243
244USER_NETWORK_ALLOCATIONS_IPV6 = [
245 {
246 'id': '234dbb10-9a36-46f2-8d89-3d909830c356',
247 'ip_address': 'fd68:1a09:66ab:8d51:0:10:0:1',
248 'cidr': 'fd68:1a09:66ab:8d51::/64',
249 'segmentation_id': '2000',
250 'network_type': 'vlan',
251 'label': 'user',
252 'mtu': MTU,
253 'gateway': 'fd68:1a09:66ab:8d51:0:0:0:1',
254 },
255 {
256 'id': '6677deed-bad2-46ea-bd0f-a33884c869e0',
257 'ip_address': 'fd68:1a09:66ab:8d51:0:10:0:2',
258 'cidr': 'fd68:1a09:66ab:8d51::/64',
259 'segmentation_id': '2000',
260 'network_type': 'vlan',
261 'label': 'user',
262 'mtu': MTU,
263 'gateway': 'fd68:1a09:66ab:8d51:0:0:0:1',
239 } 264 }
240] 265]
241 266
@@ -248,6 +273,7 @@ ADMIN_NETWORK_ALLOCATIONS = [
248 'network_type': 'flat', 273 'network_type': 'flat',
249 'label': 'admin', 274 'label': 'admin',
250 'mtu': MTU, 275 'mtu': MTU,
276 'gateway': '10.10.20.1'
251 }, 277 },
252] 278]
253 279
@@ -611,3 +637,11 @@ def get_config_cmode():
611 config.netapp_volume_snapshot_reserve_percent = 8 637 config.netapp_volume_snapshot_reserve_percent = 8
612 config.netapp_vserver = VSERVER1 638 config.netapp_vserver = VSERVER1
613 return config 639 return config
640
641
642def get_network_info(user_network_allocation, admin_network_allocation):
643 net_info = copy.deepcopy(NETWORK_INFO)
644 net_info['network_allocations'] = user_network_allocation
645 net_info['admin_network_allocations'] = admin_network_allocation
646
647 return net_info
diff --git a/releasenotes/notes/bug-1698258-netapp-fix-tenant-network-gateways-85935582e89a72a0.yaml b/releasenotes/notes/bug-1698258-netapp-fix-tenant-network-gateways-85935582e89a72a0.yaml
new file mode 100644
index 0000000..289faa0
--- /dev/null
+++ b/releasenotes/notes/bug-1698258-netapp-fix-tenant-network-gateways-85935582e89a72a0.yaml
@@ -0,0 +1,7 @@
1---
2fixes:
3 - The NetApp DHSS=True driver now creates static routes with the gateway
4 specified on the tenant networks. Potential beneficiaries of this bug-fix
5 are deployers/users whose CIFS security service (e.g. Active Directory)
6 is not part of the tenant network, but a route exists via the tenant
7 network gateway.