From 49848a7674b3a502e7cf6d610f0dc5d2dddbd642 Mon Sep 17 00:00:00 2001 From: Simon Dodsley Date: Thu, 20 May 2021 13:36:58 -0400 Subject: [PATCH] [Pure Storage] Fix minimum SDK version required Change method to check supported REST version on the backend. This will mkae it easier to specify minimum REST versions for specific feature support. Closes-Bug: #1929219 Change-Id: Ibab932d3536d44dd7414560768ed5bdeaa9e61e1 --- cinder/tests/unit/volume/drivers/test_pure.py | 98 ++++++++++++++----- cinder/volume/drivers/pure.py | 87 ++++++++-------- driver-requirements.txt | 2 +- lower-constraints.txt | 2 +- ...e_sdk_version_checks-257cb8387ed6f5f8.yaml | 11 +++ setup.cfg | 4 +- 6 files changed, 131 insertions(+), 73 deletions(-) create mode 100644 releasenotes/notes/pure_sdk_version_checks-257cb8387ed6f5f8.yaml diff --git a/cinder/tests/unit/volume/drivers/test_pure.py b/cinder/tests/unit/volume/drivers/test_pure.py index 0ce22689b40..b5ac9190904 100644 --- a/cinder/tests/unit/volume/drivers/test_pure.py +++ b/cinder/tests/unit/volume/drivers/test_pure.py @@ -104,7 +104,6 @@ PURE_HOST = { "iqn": [], "wwn": [], } -REST_VERSION = "1.2" INITIATOR_IQN = "iqn.1993-08.org.debian:01:222" INITIATOR_WWN = "5001500150015081abc" ISCSI_CONNECTOR = {"initiator": INITIATOR_IQN, "host": HOSTNAME} @@ -626,9 +625,15 @@ class PureBaseSharedDriverTestCase(PureDriverTestCase): self.driver._array = self.array self.driver._replication_pod_name = 'cinder-pod' self.driver._replication_pg_name = 'cinder-group' - self.array.get_rest_version.return_value = '1.4' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.purestorage_module.FlashArray.side_effect = None - self.async_array2.get_rest_version.return_value = '1.4' + self.async_array2._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] def new_fake_vol(self, set_provider_id=True, fake_context=None, spec=None, type_extra_specs=None, type_qos_specs_id=None, @@ -801,7 +806,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): ] mock_target = mock.MagicMock() mock_target.get.return_value = GET_ARRAY_PRIMARY - mock_target.get_rest_version.return_value = '1.14' + mock_target._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.purestorage_module.FlashArray.return_value = mock_target self.driver.parse_replication_configs() @@ -838,7 +846,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): ] mock_target = mock.MagicMock() mock_target.get.return_value = GET_ARRAY_PRIMARY - mock_target.get_rest_version.return_value = '1.14' + mock_target._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.purestorage_module.FlashArray.return_value = mock_target self.driver.parse_replication_configs() @@ -899,9 +910,15 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): ] mock_sync_target = mock.MagicMock() mock_sync_target.get.return_value = GET_ARRAY_SECONDARY - mock_sync_target.get_rest_version.return_value = '1.14' + mock_sync_target._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.array.get.return_value = GET_ARRAY_PRIMARY - self.array.get_rest_version.return_value = '1.14' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.purestorage_module.FlashArray.side_effect = [self.array, mock_sync_target] self.driver.do_setup(None) @@ -1251,7 +1268,8 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): }] self.driver.delete_volume(vol) - expected = [mock.call.list_volume_private_connections(vol_name), + expected = [mock.call.list_volume_private_connections(vol_name, + remote=True), mock.call.disconnect_host(host_name_a, vol_name), mock.call.list_host_connections(host_name_a, private=True), mock.call.disconnect_host(host_name_b, vol_name), @@ -1267,7 +1285,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): vol, vol_name = self.new_fake_vol(type_extra_specs=type_spec) self.array.list_volume_private_connections.return_value = [] # Set the array to be in a sync-rep enabled version - self.array.get_rest_version.return_value = "1.14" + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.driver.delete_volume(vol) @@ -1307,11 +1328,14 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): ] # Set the array to be in a sync-rep enabled version - self.array.get_rest_version.return_value = "1.14" + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.driver.delete_volume(vol) expected = [ - mock.call.get_rest_version(), + mock.call._list_available_rest_versions(), mock.call.list_volume_private_connections(vol_name, remote=True), mock.call.disconnect_host(host_name_a, vol_name), mock.call.list_host_connections(host_name_a, private=True), @@ -2180,7 +2204,8 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): snap, snap_ref) def test_manage_existing_snapshot_bad_api_version(self): - self.array.get_rest_version.return_value = '1.3' + self.array._list_available_rest_versions.return_value = ['1.0', '1.1', + '1.2'] snap, _ = self.new_fake_snap() self.assertRaises(pure.PureDriverException, self.driver.manage_existing_snapshot, @@ -2239,7 +2264,8 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): def test_manage_existing_snapshot_get_size_bad_api_version(self): snap, _ = self.new_fake_snap() - self.array.get_rest_version.return_value = '1.3' + self.array._list_available_rest_versions.return_value = ['1.0', '1.1', + '1.2'] self.assertRaises(pure.PureDriverException, self.driver.manage_existing_snapshot_get_size, snap, {'name': PURE_SNAPSHOT['name']}) @@ -2288,7 +2314,8 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): def test_unmanage_snapshot_bad_api_version(self): snap, _ = self.new_fake_snap() - self.array.get_rest_version.return_value = '1.3' + self.array._list_available_rest_versions.return_value = ['1.0', '1.1', + '1.2'] self.assertRaises(pure.PureDriverException, self.driver.unmanage_snapshot, snap) @@ -3108,7 +3135,7 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): san_ip = '1.2.3.4' api_token = 'abcdef' self.purestorage_module.FlashArray.return_value = mock.MagicMock() - self.purestorage_module.VERSION = "1.14.0" + self.purestorage_module.VERSION = "1.17.0" self.driver._get_flasharray(san_ip, api_token, @@ -3217,7 +3244,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): type_qos_specs_id=qos.id) mock_get_volume_type.return_value = vol.volume_type - self.array.get_rest_version.return_value = '1.17' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] mock_get_qos_specs.return_value = qos mock_get_repl_type.return_value = None @@ -3247,7 +3277,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): type_qos_specs_id=qos.id) mock_get_volume_type.return_value = vol.volume_type - self.array.get_rest_version.return_value = '1.17' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] mock_get_qos_specs.return_value = qos mock_get_repl_type.return_value = None @@ -3277,7 +3310,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): mock_get_volume_type.return_value = vol.volume_type mock_get_qos_specs.return_value = qos self.array.list_volume_private_connections.return_value = [] - self.array.get_rest_version.return_value = '1.17' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] self.driver.manage_existing(vol, volume_ref) self.array.list_volume_private_connections.assert_called_with(ref_name) @@ -3294,7 +3330,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): new_type = fake_volume.fake_volume_type_obj(mock_context) new_type.qos_specs_id = qos.id - self.array.get_rest_version.return_value = '1.17' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] get_voltype = "cinder.objects.volume_type.VolumeType.get_by_name_or_id" with mock.patch(get_voltype) as mock_get_vol_type: mock_get_vol_type.return_value = new_type @@ -3318,7 +3357,10 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): vol, vol_name = self.new_fake_vol() new_type = fake_volume.fake_volume_type_obj(mock_context) - self.array.get_rest_version.return_value = '1.17' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] get_voltype = "cinder.objects.volume_type.VolumeType.get_by_name_or_id" with mock.patch(get_voltype) as mock_get_vol_type: mock_get_vol_type.return_value = new_type @@ -3697,13 +3739,19 @@ class PureISCSIDriverTestCase(PureBaseSharedDriverTestCase): self.mock_config.use_chap_auth = False self.mock_config.safe_get.return_value = 'oracle-vm-server' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11'] # Branch where we fail due to invalid version for setting personality self.assertRaises(pure.PureDriverException, self.driver._connect, self.array, vol_name, ISCSI_CONNECTOR, None, None) self.assertFalse(self.array.create_host.called) self.assertFalse(self.array.set_host.called) - self.array.get_rest_version.return_value = '1.14' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] # Branch where personality is set self.driver._connect(self.array, vol_name, ISCSI_CONNECTOR, @@ -3961,6 +4009,9 @@ class PureFCDriverTestCase(PureBaseSharedDriverTestCase): self.driver._connect, self.array, vol_name, FC_CONNECTOR) self.mock_config.safe_get.return_value = 'oracle-vm-server' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11'] # Branch where we fail due to invalid version for setting personality self.assertRaises(pure.PureDriverException, self.driver._connect, @@ -3968,7 +4019,10 @@ class PureFCDriverTestCase(PureBaseSharedDriverTestCase): self.assertTrue(self.array.create_host.called) self.assertFalse(self.array.set_host.called) - self.array.get_rest_version.return_value = '1.14' + self.array._list_available_rest_versions.return_value = [ + '1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', + '1.17', '1.18', '1.19'] # Branch where personality is set self.driver._connect(self.array, vol_name, FC_CONNECTOR) diff --git a/cinder/volume/drivers/pure.py b/cinder/volume/drivers/pure.py index 5dfc374b27b..7e19529eeb9 100644 --- a/cinder/volume/drivers/pure.py +++ b/cinder/volume/drivers/pure.py @@ -137,13 +137,11 @@ EXTRA_SPECS_REPL_TYPE = "replication_type" MAX_VOL_LENGTH = 63 MAX_SNAP_LENGTH = 96 UNMANAGED_SUFFIX = '-unmanaged' -QOS_REQUIRED_API_VERSION = ['1.17'] -SYNC_REPLICATION_REQUIRED_API_VERSIONS = ['1.13', '1.14', '1.17'] -ASYNC_REPLICATION_REQUIRED_API_VERSIONS = [ - '1.3', '1.4', '1.5'] + SYNC_REPLICATION_REQUIRED_API_VERSIONS -MANAGE_SNAP_REQUIRED_API_VERSIONS = [ - '1.4', '1.5'] + SYNC_REPLICATION_REQUIRED_API_VERSIONS -PERSONALITY_REQUIRED_API_VERSIONS = ['1.14'] +QOS_REQUIRED_API_VERSION = '1.17' +SYNC_REPLICATION_REQUIRED_API_VERSION = '1.13' +ASYNC_REPLICATION_REQUIRED_API_VERSION = '1.3' +MANAGE_SNAP_REQUIRED_API_VERSION = '1.4' +PERSONALITY_REQUIRED_API_VERSION = '1.14' REPL_SETTINGS_PROPAGATE_RETRY_INTERVAL = 5 # 5 seconds REPL_SETTINGS_PROPAGATE_MAX_RETRIES = 36 # 36 * 5 = 180 seconds @@ -197,9 +195,6 @@ def pure_driver_debug_trace(f): class PureBaseVolumeDriver(san.SanDriver): """Performs volume management on Pure Storage FlashArray.""" - SUPPORTED_REST_API_VERSIONS = ['1.2', '1.3', '1.4', '1.5', - '1.13', '1.14', '1.17'] - SUPPORTS_ACTIVE_ACTIVE = True PURE_QOS_KEYS = ['maxIOPS', 'maxBWS'] # ThirdPartySystems wiki page @@ -284,23 +279,21 @@ class PureBaseVolumeDriver(san.SanDriver): ssl_cert_path=ssl_cert_path ) - api_version = target_array.get_rest_version() + api_versions = target_array._list_available_rest_versions() if repl_type == REPLICATION_TYPE_ASYNC: - req_api_versions = ASYNC_REPLICATION_REQUIRED_API_VERSIONS + req_api_version = ASYNC_REPLICATION_REQUIRED_API_VERSION elif repl_type == REPLICATION_TYPE_SYNC: - req_api_versions = SYNC_REPLICATION_REQUIRED_API_VERSIONS + req_api_version = SYNC_REPLICATION_REQUIRED_API_VERSION else: msg = _('Invalid replication type specified:') % repl_type raise PureDriverException(reason=msg) - if api_version not in req_api_versions: + if req_api_version not in api_versions: msg = _('Unable to do replication with Purity REST ' - 'API version %(api_version)s, requires one of ' - '%(required_versions)s.') % { - 'api_version': api_version, - 'required_versions': - ASYNC_REPLICATION_REQUIRED_API_VERSIONS + 'API version, requires minimum of ' + '%(required_version)s.') % { + 'required_version': req_api_version } raise PureDriverException(reason=msg) @@ -377,8 +370,6 @@ class PureBaseVolumeDriver(san.SanDriver): # Raises PureDriverException if unable to connect and PureHTTPError # if unable to authenticate. - purestorage.FlashArray.supported_rest_versions = \ - self.SUPPORTED_REST_API_VERSIONS self._array = self._get_flasharray( self.configuration.san_ip, api_token=self.configuration.pure_api_token, @@ -492,9 +483,10 @@ class PureBaseVolumeDriver(san.SanDriver): ctxt = context.get_admin_context() type_id = volume.get('volume_type_id') current_array = self._get_current_array() + rest_versions = current_array._list_available_rest_versions() if type_id is not None: volume_type = volume_types.get_volume_type(ctxt, type_id) - if (current_array.get_rest_version() in QOS_REQUIRED_API_VERSION): + if QOS_REQUIRED_API_VERSION in rest_versions: qos = self._get_qos_settings(volume_type) if qos is not None: self.create_with_qos(current_array, vol_name, vol_size, qos) @@ -516,9 +508,10 @@ class PureBaseVolumeDriver(san.SanDriver): current_array = self._get_current_array() ctxt = context.get_admin_context() type_id = volume.get('volume_type_id') + rest_versions = current_array._list_available_rest_versions() if type_id is not None: volume_type = volume_types.get_volume_type(ctxt, type_id) - if (current_array.get_rest_version() in QOS_REQUIRED_API_VERSION): + if QOS_REQUIRED_API_VERSION in rest_versions: qos = self._get_qos_settings(volume_type) current_array.copy_volume(snap_name, vol_name) @@ -611,11 +604,11 @@ class PureBaseVolumeDriver(san.SanDriver): """Disconnect all hosts and delete the volume""" vol_name = self._get_vol_name(volume) current_array = self._get_current_array() + rest_versions = current_array._list_available_rest_versions() try: # Do a pass over remaining connections on the current array, if # we can try and remove any remote connections too. - if (current_array.get_rest_version() in - SYNC_REPLICATION_REQUIRED_API_VERSIONS): + if SYNC_REPLICATION_REQUIRED_API_VERSION in rest_versions: hosts = current_array.list_volume_private_connections( vol_name, remote=True) else: @@ -715,13 +708,13 @@ class PureBaseVolumeDriver(san.SanDriver): Returns True if it was the hosts last connection. """ vol_name = self._get_vol_name(volume) + rest_versions = array._list_available_rest_versions() if connector is None: # If no connector was provided it is a force-detach, remove all # host connections for the volume LOG.warning("Removing ALL host connections for volume %s", vol_name) - if (array.get_rest_version() in - SYNC_REPLICATION_REQUIRED_API_VERSIONS): + if SYNC_REPLICATION_REQUIRED_API_VERSION in rest_versions: # Remote connections are only allowed in newer API versions connections = array.list_volume_private_connections( vol_name, remote=True) @@ -1331,7 +1324,8 @@ class PureBaseVolumeDriver(san.SanDriver): # Check if the volume_type has QoS settings and if so # apply them to the newly managed volume qos = None - if (current_array.get_rest_version() in QOS_REQUIRED_API_VERSION): + rest_versions = current_array._list_available_rest_versions() + if QOS_REQUIRED_API_VERSION in rest_versions: qos = self._get_qos_settings(volume.volume_type) if qos is not None: self.set_qos(current_array, new_vol_name, qos) @@ -1400,13 +1394,12 @@ class PureBaseVolumeDriver(san.SanDriver): def _verify_manage_snap_api_requirements(self): current_array = self._get_current_array() - api_version = current_array.get_rest_version() - if api_version not in MANAGE_SNAP_REQUIRED_API_VERSIONS: + rest_versions = current_array._list_available_rest_versions() + if MANAGE_SNAP_REQUIRED_API_VERSION not in rest_versions: msg = _('Unable to do manage snapshot operations with Purity REST ' - 'API version %(api_version)s, requires ' - '%(required_versions)s.') % { - 'api_version': api_version, - 'required_versions': MANAGE_SNAP_REQUIRED_API_VERSIONS + 'API version, requires ' + '%(required_version)s.') % { + 'required_version': MANAGE_SNAP_REQUIRED_API_VERSION } raise PureDriverException(reason=msg) @@ -1573,11 +1566,11 @@ class PureBaseVolumeDriver(san.SanDriver): request_kwargs=None): if (version.LooseVersion(purestorage.VERSION) < - version.LooseVersion('1.14.0')): + version.LooseVersion('1.17.0')): if request_kwargs is not None: LOG.warning("Unable to specify request_kwargs='%s' on " "purestorage.FlashArray using 'purestorage' " - "python module <1.14.0. Current version: %s", + "python module <1.17.0. Current version: %s", request_kwargs, purestorage.VERSION) array = purestorage.FlashArray(san_ip, @@ -1927,7 +1920,8 @@ class PureBaseVolumeDriver(san.SanDriver): # make sure the volume gets the correct new QoS settings. # This could mean removing existing QoS settings. current_array = self._get_current_array() - if (current_array.get_rest_version() in QOS_REQUIRED_API_VERSION): + rest_versions = current_array._list_available_rest_versions() + if QOS_REQUIRED_API_VERSION in rest_versions: qos = self._get_qos_settings(new_type) vol_name = self._generate_purity_vol_name(volume) if qos is not None: @@ -2079,17 +2073,16 @@ class PureBaseVolumeDriver(san.SanDriver): @pure_driver_debug_trace def get_check_personality(self, array): personality = self.configuration.safe_get('pure_host_personality') + rest_versions = array._list_available_rest_versions() if personality: - api_version = array.get_rest_version() - if api_version not in PERSONALITY_REQUIRED_API_VERSIONS: + if PERSONALITY_REQUIRED_API_VERSION not in rest_versions: # Continuing here would mean creating a host not according # to specificiations, possibly leading to unexpected # behavior later on. msg = _('Unable to set host personality with Purity REST ' - 'API version %(api_version)s, requires ' - '%(required_versions)s.') % { - 'api_version': api_version, - 'required_versions': PERSONALITY_REQUIRED_API_VERSIONS + 'API version, requires ' + '%(required_version)s.') % { + 'required_version': PERSONALITY_REQUIRED_API_VERSION } raise PureDriverException(reason=msg) return personality @@ -2578,8 +2571,8 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver): def _get_host(self, array, connector, remote=False): """Return dict describing existing Purity host object or None.""" - if (remote and array.get_rest_version() in - SYNC_REPLICATION_REQUIRED_API_VERSIONS): + rest_versions = array._list_available_rest_versions() + if remote and SYNC_REPLICATION_REQUIRED_API_VERSION in rest_versions: hosts = array.list_hosts(remote=True) else: hosts = array.list_hosts() @@ -2805,8 +2798,8 @@ class PureFCDriver(PureBaseVolumeDriver, driver.FibreChannelDriver): def _get_host(self, array, connector, remote=False): """Return dict describing existing Purity host object or None.""" - if (remote and array.get_rest_version() in - SYNC_REPLICATION_REQUIRED_API_VERSIONS): + rest_versions = array._list_available_rest_versions() + if remote and SYNC_REPLICATION_REQUIRED_API_VERSION in rest_versions: hosts = array.list_hosts(remote=True) else: hosts = array.list_hosts() diff --git a/driver-requirements.txt b/driver-requirements.txt index 307153250c4..cc8da8eb53a 100644 --- a/driver-requirements.txt +++ b/driver-requirements.txt @@ -9,7 +9,7 @@ python-3parclient>=4.2.10 # Apache-2.0 krest>=1.3.0 # Apache-2.0 # Pure Storage -purestorage>=1.6.0 # BSD +purestorage>=1.17.0 # BSD # Dell EMC VMAX, IBM DS8K pyOpenSSL>=1.0.0 # Apache-2.0 diff --git a/lower-constraints.txt b/lower-constraints.txt index 1358e87debb..78462293a83 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -147,7 +147,7 @@ infinisdk==103.0.1 capacity==1.3.10 info.dtypes.wwn==0.1.1 info.dtypes.iqn==0.4.0 -purestorage==1.6.0 +purestorage==1.17.0 rsd-lib==1.1.0 storpool==4.0.0 storpool.spopenstack==2.2.1 diff --git a/releasenotes/notes/pure_sdk_version_checks-257cb8387ed6f5f8.yaml b/releasenotes/notes/pure_sdk_version_checks-257cb8387ed6f5f8.yaml new file mode 100644 index 00000000000..d909d24ffc7 --- /dev/null +++ b/releasenotes/notes/pure_sdk_version_checks-257cb8387ed6f5f8.yaml @@ -0,0 +1,11 @@ +--- +upgrade: + - | + Pure Storage FlashArray minimum ``purestorage`` SDK version increased + to 1.17.0 +fixes: + - | + Pure Storage FlashArray driver `bug #1929219 + `_: Fixes issue with + incorrect internal mechanism for checking REST API of backend array. + This has no external effect for users. diff --git a/setup.cfg b/setup.cfg index cd1057dcb49..212c24d482c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -85,7 +85,7 @@ all = python-3parclient>=4.1.0 # Apache-2.0 krest>=1.3.0 # Apache-2.0 infinisdk>=103.0.1 # BSD-3 - purestorage>=1.6.0 # BSD + purestorage>=1.17.0 # BSD rsd-lib>=1.1.0 # Apache-2.0 storpool>=4.0.0 # Apache-2.0 storpool.spopenstack>=2.2.1 # Apache-2.0 @@ -110,7 +110,7 @@ ds8k = infinidat = infinisdk>=103.0.1 # BSD-3 pure = - purestorage>=1.6.0 # BSD + purestorage>=1.17.0 # BSD rsd = rsd-lib>=1.1.0 # Apache-2.0 storpool =