diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode.py b/manila/share/drivers/netapp/dataontap/client/client_cmode.py index d6357d19..119a7b7e 100644 --- a/manila/share/drivers/netapp/dataontap/client/client_cmode.py +++ b/manila/share/drivers/netapp/dataontap/client/client_cmode.py @@ -66,6 +66,8 @@ class NetAppCmodeClient(client_base.NetAppBaseClient): self.features.add_feature('IPSPACES', supported=ontapi_1_30) self.features.add_feature('SUBNETS', supported=ontapi_1_30) self.features.add_feature('CLUSTER_PEER_POLICY', supported=ontapi_1_30) + self.features.add_feature('ADVANCED_DISK_PARTITIONING', + supported=ontapi_1_30) def _invoke_vserver_api(self, na_element, vserver): server = copy.copy(self.connection) @@ -2367,76 +2369,116 @@ class NetAppCmodeClient(client_base.NetAppBaseClient): LOG.warning(_LW('Failed to invoke EMS. %s') % e) @na_utils.trace - def get_aggregate_raid_types(self, aggregate_names): - """Get the RAID type of one or more aggregates.""" + def get_aggregate(self, aggregate_name): + """Get aggregate attributes needed for the storage service catalog.""" + + if not aggregate_name: + return {} desired_attributes = { 'aggr-attributes': { 'aggregate-name': None, 'aggr-raid-attributes': { 'raid-type': None, + 'is-hybrid': None, }, }, } - aggr_list = self._get_aggregates(aggregate_names=aggregate_names, + + try: + aggrs = self._get_aggregates(aggregate_names=[aggregate_name], desired_attributes=desired_attributes) + except netapp_api.NaApiError: + msg = _('Failed to get info for aggregate %s.') + LOG.exception(msg % aggregate_name) + return {} - aggr_raid_dict = {} - for aggr in aggr_list: - aggr_name = aggr.get_child_content('aggregate-name') - aggr_raid_attrs = aggr.get_child_by_name('aggr-raid-attributes') + if len(aggrs) < 1: + return {} - aggr_raid_dict[aggr_name] = aggr_raid_attrs.get_child_content( - 'raid-type') + aggr_attributes = aggrs[0] + aggr_raid_attrs = aggr_attributes.get_child_by_name( + 'aggr-raid-attributes') or netapp_api.NaElement('none') - return aggr_raid_dict + aggregate = { + 'name': aggr_attributes.get_child_content('aggregate-name'), + 'raid-type': aggr_raid_attrs.get_child_content('raid-type'), + 'is-hybrid': strutils.bool_from_string( + aggr_raid_attrs.get_child_content('is-hybrid')), + } + + return aggregate @na_utils.trace - def get_aggregate_disk_types(self, aggregate_names): - """Get the disk type of one or more aggregates.""" + def get_aggregate_disk_types(self, aggregate_name): + """Get the disk type(s) of an aggregate.""" - aggr_disk_type_dict = {} + disk_types = set() + disk_types.update(self._get_aggregate_disk_types(aggregate_name)) + if self.features.ADVANCED_DISK_PARTITIONING: + disk_types.update(self._get_aggregate_disk_types(aggregate_name, + shared=True)) - for aggregate_name in aggregate_names: + return list(disk_types) if disk_types else None - # Only get 1 disk, since apart from hybrid aggregates all disks - # must be the same type. - api_args = { - 'max-records': 1, - 'query': { - 'storage-disk-info': { - 'disk-raid-info': { - 'disk-aggregate-info': { - 'aggregate-name': aggregate_name, - }, - }, - }, - }, - 'desired-attributes': { - 'storage-disk-info': { - 'disk-raid-info': { - 'effective-disk-type': None, + @na_utils.trace + def _get_aggregate_disk_types(self, aggregate_name, shared=False): + """Get the disk type(s) of an aggregate.""" + + disk_types = set() + + if shared: + disk_raid_info = { + 'disk-shared-info': { + 'aggregate-list': { + 'shared-aggregate-info': { + 'aggregate-name': aggregate_name, }, }, }, } - result = self.send_request('storage-disk-get-iter', api_args) + else: + disk_raid_info = { + 'disk-aggregate-info': { + 'aggregate-name': aggregate_name, + }, + } - attributes_list = result.get_child_by_name( - 'attributes-list') or netapp_api.NaElement('none') - storage_disk_info_list = attributes_list.get_children() + api_args = { + 'query': { + 'storage-disk-info': { + 'disk-raid-info': disk_raid_info, + }, + }, + 'desired-attributes': { + 'storage-disk-info': { + 'disk-raid-info': { + 'effective-disk-type': None, + }, + }, + }, + } + + try: + result = self.send_iter_request('storage-disk-get-iter', api_args) + except netapp_api.NaApiError: + msg = _('Failed to get disk info for aggregate %s.') + LOG.exception(msg % aggregate_name) + return disk_types + + attributes_list = result.get_child_by_name( + 'attributes-list') or netapp_api.NaElement('none') + + for storage_disk_info in attributes_list.get_children(): - if len(storage_disk_info_list) >= 1: - storage_disk_info = storage_disk_info_list[0] disk_raid_info = storage_disk_info.get_child_by_name( - 'disk-raid-info') - if disk_raid_info: - disk_type = disk_raid_info.get_child_content( - 'effective-disk-type') - if disk_type: - aggr_disk_type_dict[aggregate_name] = disk_type + 'disk-raid-info') or netapp_api.NaElement('none') + disk_type = disk_raid_info.get_child_content( + 'effective-disk-type') + if disk_type: + disk_types.add(disk_type) - return aggr_disk_type_dict + return disk_types @na_utils.trace def check_for_cluster_credentials(self): diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py index 4a5b2169..941d91de 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py @@ -278,6 +278,7 @@ class NetAppCmodeFileStorageLibrary(object): 'dedupe': [True, False], 'compression': [True, False], 'thin_provisioning': [True, False], + 'netapp_aggregate': aggr_name, } # Add storage service catalog data. @@ -1107,13 +1108,18 @@ class NetAppCmodeFileStorageLibrary(object): if not self._have_cluster_creds: return - raid_types = self._client.get_aggregate_raid_types(aggregate_names) - for aggregate_name, raid_type in raid_types.items(): - ssc_stats[aggregate_name]['netapp_raid_type'] = raid_type + for aggregate_name in aggregate_names: - disk_types = self._client.get_aggregate_disk_types(aggregate_names) - for aggregate_name, disk_type in disk_types.items(): - ssc_stats[aggregate_name]['netapp_disk_type'] = disk_type + aggregate = self._client.get_aggregate(aggregate_name) + hybrid = (six.text_type(aggregate.get('is-hybrid')).lower() + if 'is-hybrid' in aggregate else None) + disk_types = self._client.get_aggregate_disk_types(aggregate_name) + + ssc_stats[aggregate_name].update({ + 'netapp_raid_type': aggregate.get('raid-type'), + 'netapp_hybrid_aggregate': hybrid, + 'netapp_disk_type': disk_types, + }) def _find_active_replica(self, replica_list): # NOTE(ameade): Find current active replica. There can only be one diff --git a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py index 8db9ff4f..18f450f6 100644 --- a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py @@ -43,6 +43,7 @@ SHARE_AGGREGATE_NAME = 'fake_aggr1' SHARE_AGGREGATE_NAMES = ('fake_aggr1', 'fake_aggr2') SHARE_AGGREGATE_RAID_TYPES = ('raid4', 'raid_dp') SHARE_AGGREGATE_DISK_TYPE = 'FCAL' +SHARE_AGGREGATE_DISK_TYPES = ['SATA', 'SSD'] SHARE_NAME = 'fake_share' SHARE_SIZE = '1000000000' SHARE_NAME_2 = 'fake_share_2' @@ -1145,6 +1146,127 @@ AGGR_GET_ITER_RESPONSE = etree.XML(""" 'aggr2': SHARE_AGGREGATE_NAMES[1], }) +AGGR_GET_ITER_SSC_RESPONSE = etree.XML(""" + + + + + + false + + + + 64_bit + 1758646411 + aggr + + + 512 + 30384 + 96 + 30384 + 30384 + 30384 + 243191 + 96 + 0 + + + 4082368507 + cluster3-01 + 4082368507 + cluster3-01 + + + off + 0 + + + active + block + 3 + cfo + true + false + true + false + false + false + unmirrored + online + 1 + + + true + false + /%(aggr1)s/plex0 + normal,active + + + block + false + false + false + /%(aggr1)s/plex0/rg0 + 0 + 0 + + + 0 + + + on + 16 + raid_dp, normal + raid_dp + online + + + false + + + 0 + 0 + true + true + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 245760 + 0 + 95 + 45670400 + 943718400 + 898048000 + 0 + 898048000 + 897802240 + + + 1 + 0 + 0 + + %(aggr1)s + 15863632-ea49-49a8-9c88-2bd2d57c6d7a + + cluster3-01 + + unknown + + + 1 + +""" % {'aggr1': SHARE_AGGREGATE_NAMES[0]}) + VOLUME_GET_NAME_RESPONSE = etree.XML(""" @@ -1476,13 +1598,34 @@ STORAGE_DISK_GET_ITER_RESPONSE = etree.XML(""" cluster3-01:v5.19 - %s + %(type0)s + + + + cluster3-01:v5.20 + + %(type0)s + + + + cluster3-01:v5.20 + + %(type1)s + + + + cluster3-01:v5.20 + + %(type1)s - 1 + 4 -""" % SHARE_AGGREGATE_DISK_TYPE) +""" % { + 'type0': SHARE_AGGREGATE_DISK_TYPES[0], + 'type1': SHARE_AGGREGATE_DISK_TYPES[1], +}) STORAGE_DISK_GET_ITER_RESPONSE_PAGE_1 = etree.XML(""" 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 2f03fff9..3055a265 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 @@ -189,7 +189,7 @@ class NetAppClientCmodeTestCase(test.TestCase): max_page_length=10) num_records = result.get_child_content('num-records') - self.assertEqual('1', num_records) + self.assertEqual('4', num_records) args = copy.deepcopy(storage_disk_get_iter_args) args['max-records'] = 10 @@ -4184,90 +4184,185 @@ class NetAppClientCmodeTestCase(test.TestCase): mock.call('ems-autosupport-log', fake.EMS_MESSAGE)]) self.assertEqual(1, client_cmode.LOG.warning.call_count) - def test_get_aggregate_raid_types(self): + def test_get_aggregate_none_specified(self): - api_response = netapp_api.NaElement(fake.AGGR_GET_RAID_TYPE_RESPONSE) + result = self.client.get_aggregate('') + + self.assertEqual({}, result) + + def test_get_aggregate(self): + + api_response = netapp_api.NaElement( + fake.AGGR_GET_ITER_SSC_RESPONSE).get_child_by_name( + 'attributes-list').get_children() self.mock_object(self.client, - 'send_iter_request', + '_get_aggregates', mock.Mock(return_value=api_response)) - result = self.client.get_aggregate_raid_types( - fake.SHARE_AGGREGATE_NAMES) + result = self.client.get_aggregate(fake.SHARE_AGGREGATE_NAME) - aggr_get_iter_args = { - 'query': { - 'aggr-attributes': { - 'aggregate-name': '|'.join(fake.SHARE_AGGREGATE_NAMES), - } + desired_attributes = { + 'aggr-attributes': { + 'aggregate-name': None, + 'aggr-raid-attributes': { + 'raid-type': None, + 'is-hybrid': None, + }, }, - 'desired-attributes': { - 'aggr-attributes': { - 'aggregate-name': None, - 'aggr-raid-attributes': { - 'raid-type': None, - } - } - } } + self.client._get_aggregates.assert_has_calls([ + mock.call( + aggregate_names=[fake.SHARE_AGGREGATE_NAME], + desired_attributes=desired_attributes)]) expected = { - fake.SHARE_AGGREGATE_NAMES[0]: - fake.SHARE_AGGREGATE_RAID_TYPES[0], - fake.SHARE_AGGREGATE_NAMES[1]: - fake.SHARE_AGGREGATE_RAID_TYPES[1] + 'name': fake.SHARE_AGGREGATE_NAME, + 'raid-type': 'raid_dp', + 'is-hybrid': False, } + self.assertEqual(expected, result) - self.client.send_iter_request.assert_has_calls([ - mock.call('aggr-get-iter', aggr_get_iter_args)]) - self.assertDictEqual(expected, result) - - def test_get_aggregate_raid_types_not_found(self): + def test_get_aggregate_not_found(self): api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE) self.mock_object(self.client, - 'send_iter_request', + 'send_request', mock.Mock(return_value=api_response)) - result = self.client.get_aggregate_raid_types( - fake.SHARE_AGGREGATE_NAMES) + result = self.client.get_aggregate(fake.SHARE_AGGREGATE_NAME) - self.assertDictEqual({}, result) + self.assertEqual({}, result) - def test_get_aggregate_disk_types(self): + def test_get_aggregate_api_error(self): + + self.mock_object(self.client, + 'send_request', + mock.Mock(side_effect=self._mock_api_error())) + + result = self.client.get_aggregate(fake.SHARE_AGGREGATE_NAME) + + self.assertEqual({}, result) + + @ddt.data({'types': {'FCAL'}, 'expected': ['FCAL']}, + {'types': {'SATA', 'SSD'}, 'expected': ['SATA', 'SSD']},) + @ddt.unpack + def test_get_aggregate_disk_types(self, types, expected): + + mock_get_aggregate_disk_types = self.mock_object( + self.client, '_get_aggregate_disk_types', + mock.Mock(return_value=types)) + + result = self.client.get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME) + + self.assertItemsEqual(expected, result) + mock_get_aggregate_disk_types.assert_called_once_with( + fake.SHARE_AGGREGATE_NAME) + + def test_get_aggregate_disk_types_not_found(self): + + mock_get_aggregate_disk_types = self.mock_object( + self.client, '_get_aggregate_disk_types', + mock.Mock(return_value=set())) + + result = self.client.get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME) + + self.assertIsNone(result) + mock_get_aggregate_disk_types.assert_called_once_with( + fake.SHARE_AGGREGATE_NAME) + + def test_get_aggregate_disk_types_shared(self): + + self.client.features.add_feature('ADVANCED_DISK_PARTITIONING') + mock_get_aggregate_disk_types = self.mock_object( + self.client, '_get_aggregate_disk_types', + mock.Mock(side_effect=[set(['SSD']), set(['SATA'])])) + + result = self.client.get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME) + + self.assertIsInstance(result, list) + self.assertItemsEqual(['SATA', 'SSD'], result) + mock_get_aggregate_disk_types.assert_has_calls([ + mock.call(fake.SHARE_AGGREGATE_NAME), + mock.call(fake.SHARE_AGGREGATE_NAME, shared=True), + ]) + + @ddt.data({ + 'shared': False, + 'query_disk_raid_info': { + 'disk-aggregate-info': { + 'aggregate-name': fake.SHARE_AGGREGATE_NAME, + }, + }, + }, { + 'shared': True, + 'query_disk_raid_info': { + 'disk-shared-info': { + 'aggregate-list': { + 'shared-aggregate-info': { + 'aggregate-name': + fake.SHARE_AGGREGATE_NAME, + }, + }, + }, + }, + }) + @ddt.unpack + def test__get_aggregate_disk_types_ddt(self, shared, query_disk_raid_info): api_response = netapp_api.NaElement( fake.STORAGE_DISK_GET_ITER_RESPONSE) self.mock_object(self.client, - 'send_request', + 'send_iter_request', mock.Mock(return_value=api_response)) - result = self.client.get_aggregate_disk_types( - fake.SHARE_AGGREGATE_NAMES) + result = self.client._get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME, shared=shared) - expected = { - fake.SHARE_AGGREGATE_NAMES[0]: - fake.SHARE_AGGREGATE_DISK_TYPE, - fake.SHARE_AGGREGATE_NAMES[1]: - fake.SHARE_AGGREGATE_DISK_TYPE + storage_disk_get_iter_args = { + 'query': { + 'storage-disk-info': { + 'disk-raid-info': query_disk_raid_info, + }, + }, + 'desired-attributes': { + 'storage-disk-info': { + 'disk-raid-info': { + 'effective-disk-type': None, + }, + }, + }, } + self.client.send_iter_request.assert_called_once_with( + 'storage-disk-get-iter', storage_disk_get_iter_args) - self.assertEqual(len(fake.SHARE_AGGREGATE_NAMES), - self.client.send_request.call_count) - self.assertDictEqual(expected, result) + expected = set(fake.SHARE_AGGREGATE_DISK_TYPES) + self.assertEqual(expected, result) - def test_get_aggregate_disk_types_not_found(self): + def test__get_aggregate_disk_types_not_found(self): api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE) self.mock_object(self.client, - 'send_request', + 'send_iter_request', mock.Mock(return_value=api_response)) - result = self.client.get_aggregate_disk_types( - fake.SHARE_AGGREGATE_NAMES) + result = self.client._get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME) - self.assertEqual(len(fake.SHARE_AGGREGATE_NAMES), - self.client.send_request.call_count) - self.assertDictEqual({}, result) + self.assertEqual(set(), result) + + def test__get_aggregate_disk_types_api_error(self): + + self.mock_object(self.client, + 'send_iter_request', + mock.Mock(side_effect=self._mock_api_error())) + + result = self.client._get_aggregate_disk_types( + fake.SHARE_AGGREGATE_NAME) + + self.assertEqual(set([]), result) def test_check_for_cluster_credentials(self): diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py index 7a18724d..a7c03cc4 100644 --- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py +++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py @@ -378,27 +378,28 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.assertListEqual(fake.POOLS, result) - @ddt.data( - { - 'capacities': fake.AGGREGATE_CAPACITIES, - 'pools': fake.POOLS, - }, - { - 'capacities': fake.AGGREGATE_CAPACITIES_VSERVER_CREDS, - 'pools': fake.POOLS_VSERVER_CREDS - } - ) - @ddt.unpack - def test_get_pools(self, capacities, pools): + def test_get_pools(self): - self.mock_object(self.library, - '_get_aggregate_space', - mock.Mock(return_value=capacities)) + self.mock_object( + self.library, '_get_aggregate_space', + mock.Mock(return_value=fake.AGGREGATE_CAPACITIES)) + self.library._have_cluster_creds = True self.library._ssc_stats = fake.SSC_INFO result = self.library._get_pools() - self.assertListEqual(pools, result) + self.assertListEqual(fake.POOLS, result) + + def test_get_pools_vserver_creds(self): + + self.mock_object( + self.library, '_get_aggregate_space', + mock.Mock(return_value=fake.AGGREGATE_CAPACITIES_VSERVER_CREDS)) + self.library._have_cluster_creds = False + + result = self.library._get_pools() + + self.assertListEqual(fake.POOLS_VSERVER_CREDS, result) def test_handle_ems_logging(self): @@ -2048,35 +2049,58 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): def test_update_ssc_aggr_info(self): self.library._have_cluster_creds = True - self.mock_object(self.client, - 'get_aggregate_raid_types', - mock.Mock(return_value=fake.SSC_RAID_TYPES)) - self.mock_object(self.client, - 'get_aggregate_disk_types', - mock.Mock(return_value=fake.SSC_DISK_TYPES)) + mock_get_aggregate = self.mock_object( + self.client, 'get_aggregate', + mock.Mock(side_effect=fake.SSC_AGGREGATES)) + mock_get_aggregate_disk_types = self.mock_object( + self.client, 'get_aggregate_disk_types', + mock.Mock(side_effect=fake.SSC_DISK_TYPES)) ssc_stats = { fake.AGGREGATES[0]: {}, - fake.AGGREGATES[1]: {} + fake.AGGREGATES[1]: {}, } self.library._update_ssc_aggr_info(fake.AGGREGATES, ssc_stats) self.assertDictEqual(fake.SSC_INFO, ssc_stats) + mock_get_aggregate.assert_has_calls([ + mock.call(fake.AGGREGATES[0]), + mock.call(fake.AGGREGATES[1]), + ]) + mock_get_aggregate_disk_types.assert_has_calls([ + mock.call(fake.AGGREGATES[0]), + mock.call(fake.AGGREGATES[1]), + ]) def test_update_ssc_aggr_info_not_found(self): self.library._have_cluster_creds = True self.mock_object(self.client, - 'get_aggregate_raid_types', + 'get_aggregate', mock.Mock(return_value={})) self.mock_object(self.client, 'get_aggregate_disk_types', - mock.Mock(return_value={})) - ssc_stats = {} + mock.Mock(return_value=None)) + ssc_stats = { + fake.AGGREGATES[0]: {}, + fake.AGGREGATES[1]: {}, + } self.library._update_ssc_aggr_info(fake.AGGREGATES, ssc_stats) - self.assertDictEqual({}, ssc_stats) + expected = { + fake.AGGREGATES[0]: { + 'netapp_raid_type': None, + 'netapp_disk_type': None, + 'netapp_hybrid_aggregate': None, + }, + fake.AGGREGATES[1]: { + 'netapp_raid_type': None, + 'netapp_disk_type': None, + 'netapp_hybrid_aggregate': None, + } + } + self.assertDictEqual(expected, ssc_stats) def test_update_ssc_aggr_info_no_cluster_creds(self): diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py index b59da1aa..d57b2f92 100644 --- a/manila/tests/share/drivers/netapp/dataontap/fakes.py +++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py @@ -493,16 +493,19 @@ AGGREGATE_CAPACITIES_VSERVER_CREDS = { SSC_INFO = { AGGREGATES[0]: { 'netapp_raid_type': 'raid4', - 'netapp_disk_type': 'FCAL' + 'netapp_disk_type': 'FCAL', + 'netapp_hybrid_aggregate': 'false', }, AGGREGATES[1]: { 'netapp_raid_type': 'raid_dp', - 'netapp_disk_type': 'SSD' + 'netapp_disk_type': ['SATA', 'SSD'], + 'netapp_hybrid_aggregate': 'true', } } POOLS = [ {'pool_name': AGGREGATES[0], + 'netapp_aggregate': AGGREGATES[0], 'total_capacity_gb': 3.3, 'free_capacity_gb': 1.1, 'allocated_capacity_gb': 2.2, @@ -512,9 +515,11 @@ POOLS = [ 'compression': [True, False], 'thin_provisioning': [True, False], 'netapp_raid_type': 'raid4', - 'netapp_disk_type': 'FCAL' + 'netapp_disk_type': 'FCAL', + 'netapp_hybrid_aggregate': 'false', }, {'pool_name': AGGREGATES[1], + 'netapp_aggregate': AGGREGATES[1], 'total_capacity_gb': 6.0, 'free_capacity_gb': 2.0, 'allocated_capacity_gb': 4.0, @@ -524,12 +529,14 @@ POOLS = [ 'compression': [True, False], 'thin_provisioning': [True, False], 'netapp_raid_type': 'raid_dp', - 'netapp_disk_type': 'SSD' + 'netapp_disk_type': ['SATA', 'SSD'], + 'netapp_hybrid_aggregate': 'true', }, ] POOLS_VSERVER_CREDS = [ {'pool_name': AGGREGATES[0], + 'netapp_aggregate': AGGREGATES[0], 'total_capacity_gb': 'unknown', 'free_capacity_gb': 1.1, 'allocated_capacity_gb': 0.0, @@ -538,10 +545,9 @@ POOLS_VSERVER_CREDS = [ 'dedupe': [True, False], 'compression': [True, False], 'thin_provisioning': [True, False], - 'netapp_raid_type': 'raid4', - 'netapp_disk_type': 'FCAL' }, {'pool_name': AGGREGATES[1], + 'netapp_aggregate': AGGREGATES[1], 'total_capacity_gb': 'unknown', 'free_capacity_gb': 2.0, 'allocated_capacity_gb': 0.0, @@ -550,20 +556,23 @@ POOLS_VSERVER_CREDS = [ 'dedupe': [True, False], 'compression': [True, False], 'thin_provisioning': [True, False], - 'netapp_raid_type': 'raid_dp', - 'netapp_disk_type': 'SSD' }, ] -SSC_RAID_TYPES = { - AGGREGATES[0]: 'raid4', - AGGREGATES[1]: 'raid_dp' -} +SSC_AGGREGATES = [ + { + 'name': AGGREGATES[0], + 'raid-type': 'raid4', + 'is-hybrid': False, + }, + { + 'name': AGGREGATES[1], + 'raid-type': 'raid_dp', + 'is-hybrid': True, + }, +] -SSC_DISK_TYPES = { - AGGREGATES[0]: 'FCAL', - AGGREGATES[1]: 'SSD' -} +SSC_DISK_TYPES = ['FCAL', ['SATA', 'SSD']] def get_config_cmode(): diff --git a/releasenotes/notes/hybrid-aggregates-in-netapp-cdot-drivers-e7c90fb62426c281.yaml b/releasenotes/notes/hybrid-aggregates-in-netapp-cdot-drivers-e7c90fb62426c281.yaml new file mode 100644 index 00000000..b3bfba0f --- /dev/null +++ b/releasenotes/notes/hybrid-aggregates-in-netapp-cdot-drivers-e7c90fb62426c281.yaml @@ -0,0 +1,4 @@ +--- +features: + - Add support for hybrid aggregates to the NetApp cDOT drivers. +