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 25206dba63..0f89327d90 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 @@ -46,6 +46,8 @@ DEFAULT_MTU = 1500 CLUSTER_IPSPACES = ('Cluster', 'Default') SERVER_MIGRATE_SVM_DR = 'svm_dr' SERVER_MIGRATE_SVM_MIGRATE = 'svm_migrate' +METADATA_VLAN = 'set_vlan' +METADATA_MTU = 'set_mtu' class NetAppCmodeMultiSVMFileStorageLibrary( @@ -143,9 +145,49 @@ class NetAppCmodeMultiSVMFileStorageLibrary( return [aggr_name for aggr_name in aggregate_names if re.match(pattern, aggr_name)] + @na_utils.trace + def _set_network_with_metadata(self, network_info): + """Set the subnet metadata information for network_info object.""" + + for network in network_info: + metadata = network.get('subnet_metadata') + if not metadata: + continue + + metadata_vlan = metadata.get(METADATA_VLAN) + if not metadata_vlan: + continue + + if int(metadata_vlan) > 4094 or int(metadata_vlan) < 1: + msg = _( + 'A segmentation ID %s was specified but is not valid for ' + 'a VLAN network type; the segmentation ID must be an ' + 'integer value in the range of [1,4094]') + raise exception.NetworkBadConfigurationException( + reason=msg % metadata_vlan) + + if metadata.get(METADATA_MTU) is not None: + try: + int(metadata.get(METADATA_MTU)) + except ValueError: + msg = _('Metadata network MTU must be an integer value.') + raise exception.NetworkBadConfigurationException(msg) + + network['network_type'] = 'vlan' + network['segmentation_id'] = metadata_vlan + for allocation in network['network_allocations']: + allocation['network_type'] = 'vlan' + allocation['segmentation_id'] = metadata_vlan + allocation['mtu'] = int(metadata.get(METADATA_MTU) or + allocation['mtu']) + @na_utils.trace def setup_server(self, network_info, metadata=None): """Creates and configures new Vserver.""" + + # only changes network_info if one of networks has metadata set. + self._set_network_with_metadata(network_info) + ports = {} server_id = network_info[0]['server_id'] LOG.debug("Setting up server %s.", server_id) 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 a13454c3e7..b0382468eb 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 @@ -441,6 +441,49 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.assertListEqual([], result) + def test__set_network_with_metadata(self): + net_info_1 = copy.deepcopy(fake.NETWORK_INFO) + net_info_2 = copy.deepcopy(fake.NETWORK_INFO) + net_info_2['subnet_metadata'] = {'fake_key': 'fake_value'} + net_info_3 = copy.deepcopy(fake.NETWORK_INFO) + metadata_vlan = 1 + net_info_3['subnet_metadata'] = { + 'set_vlan': metadata_vlan, + 'set_mtu': '1' + } + net_info_4 = copy.deepcopy(fake.NETWORK_INFO) + metadata_vlan = 1 + net_info_4['subnet_metadata'] = { + 'set_vlan': metadata_vlan + } + + net_list = [net_info_1, net_info_2, net_info_3, net_info_4] + self.library._set_network_with_metadata(net_list) + + net_info = copy.deepcopy(fake.NETWORK_INFO) + self.assertEqual(net_info, net_list[0]) + net_info['subnet_metadata'] = {'fake_key': 'fake_value'} + self.assertEqual(net_info, net_list[1]) + self.assertEqual(metadata_vlan, net_list[2]['segmentation_id']) + for allocation in net_list[2]['network_allocations']: + self.assertEqual(metadata_vlan, allocation['segmentation_id']) + self.assertEqual(1, allocation['mtu']) + self.assertEqual(metadata_vlan, net_list[3]['segmentation_id']) + for allocation in net_list[3]['network_allocations']: + self.assertEqual(metadata_vlan, allocation['segmentation_id']) + self.assertEqual(fake.MTU, allocation['mtu']) + + @ddt.data({'set_vlan': '0', 'set_mtu': '1500'}, + {'set_vlan': '1000', 'set_mtu': '1bla'}) + def test__set_network_with_metadata_exception(self, metadata): + net_info = copy.deepcopy(fake.NETWORK_INFO) + net_info['subnet_metadata'] = metadata + + self.assertRaises( + exception.NetworkBadConfigurationException, + self.library._set_network_with_metadata, + [net_info]) + @ddt.data({'nfs_config_support': False}, {'nfs_config_support': True, 'nfs_config': fake.NFS_CONFIG_UDP_MAX}, @@ -472,6 +515,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.library, "_get_nfs_config_provisioning_options", mock.Mock(return_value=nfs_config)) + mock_set_with_meta = self.mock_object( + self.library, '_set_network_with_metadata') result = self.library.setup_server(fake.NETWORK_INFO_LIST, fake.SERVER_METADATA) @@ -480,6 +525,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): for network_allocation in fake.NETWORK_INFO['network_allocations']: ports[network_allocation['id']] = network_allocation['ip_address'] + mock_set_with_meta.assert_called_once_with(fake.NETWORK_INFO_LIST) self.assertTrue(mock_validate_network_type.called) self.assertTrue(mock_validate_share_network_subnets.called) self.assertTrue(mock_get_vserver_name.called) @@ -524,6 +570,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): mock_validate_share_network_subnets = self.mock_object( self.library, '_validate_share_network_subnets') + self.mock_object(self.library, '_set_network_with_metadata') self.assertRaises( exception.ManilaException, @@ -555,6 +602,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.mock_object(self.library, '_validate_network_type') self.mock_object(self.library, '_validate_share_network_subnets', mock.Mock(side_effect=invalid_subnet_exception)) + self.mock_object(self.library, '_set_network_with_metadata') self.assertRaises( exception.NetworkBadConfigurationException, diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py index e10d21aaae..d5015f1daa 100644 --- a/manila/tests/share/drivers/netapp/dataontap/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py @@ -514,6 +514,7 @@ NETWORK_INFO = { 'neutron_net_id': '4eff22ca-5ad2-454d-a000-aadfd7b40b39', 'neutron_subnet_id': '62bf1c2c-18eb-421b-8983-48a6d39aafe0', 'segmentation_id': '1000', + 'network_type': 'vlan' } NETWORK_INFO_LIST = [NETWORK_INFO] NETWORK_INFO_NETMASK = '255.255.255.0' diff --git a/releasenotes/notes/netapp_configure_net_with_metadata-c5d1b5f542967276.yaml b/releasenotes/notes/netapp_configure_net_with_metadata-c5d1b5f542967276.yaml new file mode 100644 index 0000000000..20449d159c --- /dev/null +++ b/releasenotes/notes/netapp_configure_net_with_metadata-c5d1b5f542967276.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + NetApp driver with DHSS True mode now supports setup the share server + network VLAN segmentation through share network subnet metadata. + To do so, the field `set_vlan` must be informed with VLAN number. + It can set the network MTU passing the metadata field `set_mtu`. If + the subnet metadata contains the `set_vlan` without the `set_mtu` + field the MTU is configured according to network plugin.