diff --git a/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py b/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py index 65ef05a03e9..88339e82d58 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/test_xtremio.py @@ -36,9 +36,10 @@ typ2id = {'volumes': 'vol-id', 'consistency-group-volumes': 'cg-vol-id', } -xms_init = {'xms': {1: {'version': '4.0.0'}}, +xms_init = {'xms': {1: {'version': '4.2.0', + 'sw-version': '4.2.0-30'}}, 'clusters': {1: {'name': 'brick1', - 'sys-sw-version': "4.0.0-devel_ba23ee5381eeab73", + 'sys-sw-version': "4.2.0-devel_ba23ee5381eeab73", 'ud-ssd-space': '8146708710', 'ud-ssd-space-in-use': '708710', 'vol-size': '29884416', @@ -248,16 +249,16 @@ class CommonData(object): } test_volume = fake_volume_obj(context, - name = 'vol1', - size = 1, - volume_name = 'vol1', - id = '192eb39b-6c2f-420c-bae3-3cfd117f0001', - provider_auth = None, - project_id = 'project', - display_name = 'vol1', - display_description = 'test volume', - volume_type_id = None, - consistencygroup_id = + name='vol1', + size=1, + volume_name='vol1', + id='192eb39b-6c2f-420c-bae3-3cfd117f0001', + provider_auth=None, + project_id='project', + display_name='vol1', + display_description='test volume', + volume_type_id=None, + consistencygroup_id= '192eb39b-6c2f-420c-bae3-3cfd117f0345', ) test_snapshot = D() @@ -318,16 +319,15 @@ class CommonData(object): class BaseXtremIODriverTestCase(test.TestCase): def __init__(self, *args, **kwargs): super(BaseXtremIODriverTestCase, self).__init__(*args, **kwargs) - self.config = mock.Mock(san_login = '', - san_password = '', - san_ip = '', - xtremio_cluster_name = 'brick1', - xtremio_provisioning_factor = 20.0, - max_over_subscription_ratio = 20.0, - xtremio_volumes_per_glance_cache = 100, - driver_ssl_cert_verify = True, - driver_ssl_cert_path = - '/test/path/root_ca.crt', + self.config = mock.Mock(san_login='', + san_password='', + san_ip='', + xtremio_cluster_name='brick1', + xtremio_provisioning_factor=20.0, + max_over_subscription_ratio=20.0, + xtremio_volumes_per_glance_cache=100, + driver_ssl_cert_verify=True, + driver_ssl_cert_path= '/test/path/root_ca.crt', xtremio_array_busy_retry_count=5, xtremio_array_busy_retry_interval=5) @@ -340,9 +340,9 @@ class BaseXtremIODriverTestCase(test.TestCase): clean_xms_data() self.driver = xtremio.XtremIOISCSIDriver(configuration=self.config) - self.driver.client = xtremio.XtremIOClient4(self.config, - self.config - .xtremio_cluster_name) + self.driver.client = xtremio.XtremIOClient42(self.config, + self.config + .xtremio_cluster_name) self.data = CommonData() @@ -352,6 +352,8 @@ class XtremIODriverISCSITestCase(BaseXtremIODriverTestCase): def test_check_for_setup_error(self, req): req.side_effect = xms_request self.driver.check_for_setup_error() + self.assertEqual(self.driver.client.__class__.__name__, + 'XtremIOClient42') def test_fail_check_for_setup_error(self, req): req.side_effect = xms_request @@ -360,6 +362,13 @@ class XtremIODriverISCSITestCase(BaseXtremIODriverTestCase): self.driver.check_for_setup_error) xms_data['clusters'] = clusters + def test_check_for_setup_error_ver4(self, req): + req.side_effect = xms_request + xms_data['xms'][1]['sw-version'] = '4.0.10-34.hotfix1' + self.driver.check_for_setup_error() + self.assertEqual(self.driver.client.__class__.__name__, + 'XtremIOClient4') + def test_fail_check_for_array_version(self, req): req.side_effect = xms_request cluster = xms_data['clusters'][1] @@ -1310,6 +1319,22 @@ class XtremIODriverFCTestCase(BaseXtremIODriverTestCase): self.assertEqual(1, map_data['data']['target_lun']) self.assertEqual(1, len(xms_data['initiator-groups'])) + def test_get_initiator_igs_ver4(self, req): + req.side_effect = xms_request + wwpn1 = '11:22:33:44:55:66:77:88' + wwpn2 = '11:22:33:44:55:66:77:89' + port_addresses = [wwpn1, wwpn2] + ig_id = ['', 'my_ig', 1] + self.driver.client = xtremio.XtremIOClient4(self.config, + self.config + .xtremio_cluster_name) + + def get_fake_initiator(wwpn): + return {'port-address': wwpn, 'ig-id': ig_id} + with mock.patch.object(self.driver.client, 'get_initiator', + side_effect=get_fake_initiator): + self.driver.client.get_initiators_igs(port_addresses) + def test_get_free_lun(self, req): def lm_response(*args, **kwargs): return {'lun-maps': [{'lun': 1}]} diff --git a/cinder/volume/drivers/dell_emc/xtremio.py b/cinder/volume/drivers/dell_emc/xtremio.py index 5db33b8bab0..80b9696a203 100644 --- a/cinder/volume/drivers/dell_emc/xtremio.py +++ b/cinder/volume/drivers/dell_emc/xtremio.py @@ -210,6 +210,14 @@ class XtremIOClient(object): def add_vol_to_cg(self, vol_id, cg_id): pass + def get_initiators_igs(self, port_addresses): + ig_indexes = set() + for port_address in port_addresses: + initiator = self.get_initiator(port_address) + ig_indexes.add(initiator['ig-id'][XTREMIO_OID_INDEX]) + + return list(ig_indexes) + class XtremIOClient3(XtremIOClient): def __init__(self, configuration, cluster_id): @@ -357,10 +365,21 @@ class XtremIOClient4(XtremIOClient): pass +class XtremIOClient42(XtremIOClient4): + def get_initiators_igs(self, port_addresses): + init_filter = ','.join('port-address:eq:{}'.format(port_address) for + port_address in port_addresses) + initiators = self.req('initiators', + data={'filter': init_filter, + 'full': 1, 'prop': 'ig-id'})['initiators'] + return list(set(ig_id['ig-id'][XTREMIO_OID_INDEX] + for ig_id in initiators)) + + class XtremIOVolumeDriver(san.SanDriver): """Executes commands relating to Volumes.""" - VERSION = '1.0.8' + VERSION = '1.0.9' # ThirdPartySystems wiki CI_WIKI_NAME = "EMC_XIO_CI" @@ -404,9 +423,23 @@ class XtremIOVolumeDriver(san.SanDriver): LOG.error(msg) raise exception.VolumeBackendAPIException(data=msg) else: - LOG.info('XtremIO SW version %s', version_text) + LOG.info('XtremIO Cluster version %s', version_text) + client_ver = '3' if ver[0] >= 4: - self.client = XtremIOClient4(self.configuration, self.cluster_id) + # get XMS version + xms = self.client.req('xms', idx=1)['content'] + xms_version = tuple([int(i) for i in + xms['sw-version'].split('-')[0].split('.')]) + LOG.info('XtremIO XMS version %s', version_text) + if xms_version >= (4, 2): + self.client = XtremIOClient42(self.configuration, + self.cluster_id) + client_ver = '4.2' + else: + self.client = XtremIOClient4(self.configuration, + self.cluster_id) + client_ver = '4' + LOG.info('Using XtremIO Client %s', client_ver) def create_volume(self, volume): """Creates a volume.""" @@ -633,13 +666,14 @@ class XtremIOVolumeDriver(san.SanDriver): def terminate_connection(self, volume, connector, **kwargs): """Disallow connection from connector""" - tg = self.client.req('target-groups', name='Default')['content'] - vol = self.client.req('volumes', name=volume['id'])['content'] + tg_index = '1' + vol = self.client.req('volumes', name=volume['id'], + data={'prop': 'index'})['content'] for ig_idx in self._get_ig_indexes_from_initiators(connector): lm_name = '%s_%s_%s' % (six.text_type(vol['index']), six.text_type(ig_idx), - six.text_type(tg['index'])) + tg_index) LOG.debug('Removing lun map %s.', lm_name) try: self.client.req('lun-maps', 'DELETE', name=lm_name) @@ -671,14 +705,7 @@ class XtremIOVolumeDriver(san.SanDriver): def _get_ig_indexes_from_initiators(self, connector): initiator_names = self._get_initiator_names(connector) - ig_indexes = set() - - for initiator_name in initiator_names: - initiator = self.client.get_initiator(initiator_name) - - ig_indexes.add(initiator['ig-id'][XTREMIO_OID_INDEX]) - - return list(ig_indexes) + return self.client.get_initiators_igs(initiator_names) def _get_initiator_names(self, connector): raise NotImplementedError()