From 76fd03819c08714660491ed3862ee7d6a2d92403 Mon Sep 17 00:00:00 2001 From: Helen Walsh Date: Wed, 28 Nov 2018 12:40:40 +0000 Subject: [PATCH] PowerMax driver - rebranding VMAX to PowerMax PowerMax is to replace VMAX in release notes, online documentation, directory structure and driver name. Implements: blueprint vmax-powermax-rebrand Change-Id: I74f690b60aac6d0d4bf49d25b04a067c7993bfc7 --- cinder/opts.py | 6 +- .../dell_emc/{vmax => powermax}/__init__.py | 0 .../test_powermax.py} | 1045 +++++++++-------- .../dell_emc/{vmax => powermax}/__init__.py | 0 .../dell_emc/{vmax => powermax}/common.py | 221 ++-- .../drivers/dell_emc/{vmax => powermax}/fc.py | 39 +- .../dell_emc/{vmax => powermax}/iscsi.py | 39 +- .../dell_emc/{vmax => powermax}/masking.py | 28 +- .../dell_emc/{vmax => powermax}/metadata.py | 22 +- .../dell_emc/{vmax => powermax}/provision.py | 14 +- .../dell_emc/{vmax => powermax}/rest.py | 31 +- .../dell_emc/{vmax => powermax}/utils.py | 28 +- cinder/volume/manager.py | 4 + ...river.rst => dell-emc-powermax-driver.rst} | 358 +++--- .../block-storage/volume-drivers.rst | 2 +- ...max-powermax-rebrand-70569fc8cdf40a8c.yaml | 5 + 16 files changed, 986 insertions(+), 856 deletions(-) rename cinder/tests/unit/volume/drivers/dell_emc/{vmax => powermax}/__init__.py (100%) rename cinder/tests/unit/volume/drivers/dell_emc/{vmax/test_vmax.py => powermax/test_powermax.py} (92%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/__init__.py (100%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/common.py (96%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/fc.py (95%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/iscsi.py (95%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/masking.py (99%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/metadata.py (97%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/provision.py (98%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/rest.py (99%) rename cinder/volume/drivers/dell_emc/{vmax => powermax}/utils.py (97%) rename doc/source/configuration/block-storage/drivers/{dell-emc-vmax-driver.rst => dell-emc-powermax-driver.rst} (87%) create mode 100644 releasenotes/notes/vmax-powermax-rebrand-70569fc8cdf40a8c.yaml diff --git a/cinder/opts.py b/cinder/opts.py index dd79dc861f6..f004ff6bbc9 100644 --- a/cinder/opts.py +++ b/cinder/opts.py @@ -77,6 +77,8 @@ from cinder.volume.drivers.datacore import iscsi as \ cinder_volume_drivers_datacore_iscsi from cinder.volume.drivers.datera import datera_iscsi as \ cinder_volume_drivers_datera_dateraiscsi +from cinder.volume.drivers.dell_emc.powermax import common as \ + cinder_volume_drivers_dell_emc_powermax_common from cinder.volume.drivers.dell_emc import ps as \ cinder_volume_drivers_dell_emc_ps from cinder.volume.drivers.dell_emc.sc import storagecenter_common as \ @@ -85,8 +87,6 @@ from cinder.volume.drivers.dell_emc.scaleio import driver as \ cinder_volume_drivers_dell_emc_scaleio_driver from cinder.volume.drivers.dell_emc.unity import driver as \ cinder_volume_drivers_dell_emc_unity_driver -from cinder.volume.drivers.dell_emc.vmax import common as \ - cinder_volume_drivers_dell_emc_vmax_common from cinder.volume.drivers.dell_emc.vnx import common as \ cinder_volume_drivers_dell_emc_vnx_common from cinder.volume.drivers.dell_emc import xtremio as \ @@ -284,12 +284,12 @@ def list_opts(): cinder_volume_driver.iser_opts, cinder_volume_driver.nvmet_opts, cinder_volume_drivers_datera_dateraiscsi.d_opts, + cinder_volume_drivers_dell_emc_powermax_common.powermax_opts, cinder_volume_drivers_dell_emc_ps.eqlx_opts, cinder_volume_drivers_dell_emc_sc_storagecentercommon. common_opts, cinder_volume_drivers_dell_emc_scaleio_driver.scaleio_opts, cinder_volume_drivers_dell_emc_unity_driver.UNITY_OPTS, - cinder_volume_drivers_dell_emc_vmax_common.vmax_opts, cinder_volume_drivers_dell_emc_vnx_common.VNX_OPTS, cinder_volume_drivers_dell_emc_xtremio.XTREMIO_OPTS, cinder_volume_drivers_drbdmanagedrv.drbd_opts, diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vmax/__init__.py b/cinder/tests/unit/volume/drivers/dell_emc/powermax/__init__.py similarity index 100% rename from cinder/tests/unit/volume/drivers/dell_emc/vmax/__init__.py rename to cinder/tests/unit/volume/drivers/dell_emc/powermax/__init__.py diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax.py similarity index 92% rename from cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py rename to cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax.py index 5877e5ff713..0bf80124fbd 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -39,14 +39,14 @@ from cinder.tests.unit import fake_snapshot from cinder.tests.unit import fake_volume from cinder.tests.unit import utils as test_utils from cinder import version as openstack_version -from cinder.volume.drivers.dell_emc.vmax import common -from cinder.volume.drivers.dell_emc.vmax import fc -from cinder.volume.drivers.dell_emc.vmax import iscsi -from cinder.volume.drivers.dell_emc.vmax import masking -from cinder.volume.drivers.dell_emc.vmax import metadata -from cinder.volume.drivers.dell_emc.vmax import provision -from cinder.volume.drivers.dell_emc.vmax import rest -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import common +from cinder.volume.drivers.dell_emc.powermax import fc +from cinder.volume.drivers.dell_emc.powermax import iscsi +from cinder.volume.drivers.dell_emc.powermax import masking +from cinder.volume.drivers.dell_emc.powermax import metadata +from cinder.volume.drivers.dell_emc.powermax import provision +from cinder.volume.drivers.dell_emc.powermax import rest +from cinder.volume.drivers.dell_emc.powermax import utils from cinder.volume import utils as volume_utils from cinder.volume import volume_types from cinder.zonemanager import utils as fczm_utils @@ -55,7 +55,7 @@ from cinder.zonemanager import utils as fczm_utils CINDER_EMC_CONFIG_DIR = '/etc/cinder/' -class VMAXCommonData(object): +class PowerMaxCommonData(object): # array info array = '000197800123' uni_array = u'000197800123' @@ -1024,7 +1024,7 @@ class VMAXCommonData(object): class FakeLookupService(object): def get_device_mapping_from_network(self, initiator_wwns, target_wwns): - return VMAXCommonData.device_map + return PowerMaxCommonData.device_map class FakeResponse(object): @@ -1052,7 +1052,7 @@ class FakeResponse(object): class FakeRequestsSession(object): def __init__(self, *args, **kwargs): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() def request(self, method, url, params=None, data=None): return_object = '' @@ -1334,18 +1334,18 @@ class FakeConfiguration(object): @ddt -class VMAXUtilsTest(test.TestCase): +class PowerMaxUtilsTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() volume_utils.get_max_over_subscription_ratio = mock.Mock() - super(VMAXUtilsTest, self).setUp() + super(PowerMaxUtilsTest, self).setUp() configuration = FakeConfiguration( None, 'UtilsTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = iscsi.VMAXISCSIDriver(configuration=configuration) + driver = iscsi.PowerMaxISCSIDriver(configuration=configuration) self.driver = driver self.common = self.driver.common self.utils = self.common.utils @@ -1799,19 +1799,19 @@ class VMAXUtilsTest(test.TestCase): self.utils.is_snapshot_manageable(volume)) -class VMAXRestTest(test.TestCase): +class PowerMaxRestTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXRestTest, self).setUp() + super(PowerMaxRestTest, self).setUp() volume_utils.get_max_over_subscription_ratio = mock.Mock() configuration = FakeConfiguration( None, 'RestTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = fc.VMAXFCDriver(configuration=configuration) + driver = fc.PowerMaxFCDriver(configuration=configuration) self.driver = driver self.common = self.driver.common self.rest = self.common.rest @@ -3042,8 +3042,8 @@ class VMAXRestTest(test.TestCase): sg_value, qos_extra_spec, input_prop_dict) self.assertEqual(input_prop_dict, ret_prop_dict) - @mock.patch.object(rest.VMAXRest, 'modify_storage_group', - return_value=(202, VMAXCommonData.job_list[0])) + @mock.patch.object(rest.PowerMaxRest, 'modify_storage_group', + return_value=(202, PowerMaxCommonData.job_list[0])) def test_set_storagegroup_srp(self, mock_mod): self.rest.set_storagegroup_srp( self.data.array, self.data.test_vol_grp_name, @@ -3133,7 +3133,7 @@ class VMAXRestTest(test.TestCase): self.data.device_id2, self.data.remote_array, extra_specs) self.assertEqual(ref_dict, rdf_dict) - @mock.patch.object(rest.VMAXRest, 'get_rdf_group', + @mock.patch.object(rest.PowerMaxRest, 'get_rdf_group', side_effect=[{'numDevices': 0}, {'numDevices': 0}, {'numDevices': 1}]) def test_get_metro_payload_info(self, mock_rdfg): @@ -3189,7 +3189,7 @@ class VMAXRestTest(test.TestCase): failover_payload, resource_name=resource_name, private='/private') - @mock.patch.object(rest.VMAXRest, 'delete_resource') + @mock.patch.object(rest.PowerMaxRest, 'delete_resource') def test_delete_rdf_pair(self, mock_del): self.rest.delete_rdf_pair( self.data.array, self.data.device_id, self.data.rdf_group_no) @@ -3267,7 +3267,7 @@ class VMAXRestTest(test.TestCase): @mock.patch('oslo_service.loopingcall.FixedIntervalLoopingCall', new=test_utils.ZeroIntervalLoopingCall) - @mock.patch.object(rest.VMAXRest, 'are_vols_rdf_paired', + @mock.patch.object(rest.PowerMaxRest, 'are_vols_rdf_paired', side_effect=[('', '', 'syncinprog'), ('', '', 'consistent'), exception.CinderException]) @@ -3283,7 +3283,7 @@ class VMAXRestTest(test.TestCase): self.data.device_id, self.data.device_id2, self.data.extra_specs) - @mock.patch.object(rest.VMAXRest, 'modify_resource', + @mock.patch.object(rest.PowerMaxRest, 'modify_resource', return_value=('200', 'JobComplete')) def test_modify_volume_snap_rename(self, mock_modify): array = self.data.array @@ -3313,16 +3313,16 @@ class VMAXRestTest(test.TestCase): response = [] with mock.patch.object( self.rest, 'get_resource', return_value= - VMAXCommonData.private_vol_rest_response_none): + PowerMaxCommonData.private_vol_rest_response_none): vol_list = self.rest.get_private_volume_list(array_id) self.assertEqual(response, vol_list) @mock.patch.object( - rest.VMAXRest, 'get_iterator_page_list', return_value= - VMAXCommonData.private_vol_rest_response_iterator_second['result']) + rest.PowerMaxRest, 'get_iterator_page_list', return_value= + PowerMaxCommonData.private_vol_rest_response_iterator_second['result']) @mock.patch.object( - rest.VMAXRest, 'get_resource', return_value= - deepcopy(VMAXCommonData.private_vol_rest_response_iterator_first)) + rest.PowerMaxRest, 'get_resource', return_value= + deepcopy(PowerMaxCommonData.private_vol_rest_response_iterator_first)) def test_get_private_volume_list_iterator(self, mock_get_resource, mock_iterator): array_id = self.data.array @@ -3376,8 +3376,8 @@ class VMAXRestTest(test.TestCase): self.rest.base_uri) @mock.patch.object( - rest.VMAXRest, 'get_iterator_page_list', return_value= - VMAXCommonData.private_vol_rest_response_iterator_second['result']) + rest.PowerMaxRest, 'get_iterator_page_list', return_value= + PowerMaxCommonData.private_vol_rest_response_iterator_second['result']) def test_list_pagination(self, mock_iter): result_list = self.rest.list_pagination( deepcopy(self.data.private_vol_rest_response_iterator_first)) @@ -3422,30 +3422,29 @@ class VMAXRestTest(test.TestCase): self.rest._handle_u4p_failover) -class VMAXProvisionTest(test.TestCase): +class PowerMaxProvisionTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() - - super(VMAXProvisionTest, self).setUp() + self.data = PowerMaxCommonData() + super(PowerMaxProvisionTest, self).setUp() volume_utils.get_max_over_subscription_ratio = mock.Mock() configuration = FakeConfiguration( None, 'ProvisionTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = iscsi.VMAXISCSIDriver(configuration=configuration) + driver = iscsi.PowerMaxISCSIDriver(configuration=configuration) self.driver = driver self.common = self.driver.common self.provision = self.common.provision self.utils = self.common.utils self.rest = self.common.rest - @mock.patch.object(rest.VMAXRest, 'create_storage_group', - return_value=VMAXCommonData.storagegroup_name_f) - @mock.patch.object(rest.VMAXRest, 'get_storage_group', + @mock.patch.object(rest.PowerMaxRest, 'create_storage_group', + return_value=PowerMaxCommonData.storagegroup_name_f) + @mock.patch.object(rest.PowerMaxRest, 'get_storage_group', side_effect=[ - VMAXCommonData.storagegroup_name_f, None]) + PowerMaxCommonData.storagegroup_name_f, None]) def test_create_storage_group(self, mock_get_sg, mock_create): array = self.data.array storagegroup_name = self.data.storagegroup_name_f @@ -3749,9 +3748,9 @@ class VMAXProvisionTest(test.TestCase): self.data.array, self.data.defaultstoragegroup_name)) self.assertEqual(ref_settings3, sg_slo_settings3) - @mock.patch.object(rest.VMAXRest, 'wait_for_rdf_consistent_state') - @mock.patch.object(rest.VMAXRest, 'delete_rdf_pair') - @mock.patch.object(rest.VMAXRest, 'modify_rdf_device_pair') + @mock.patch.object(rest.PowerMaxRest, 'wait_for_rdf_consistent_state') + @mock.patch.object(rest.PowerMaxRest, 'delete_rdf_pair') + @mock.patch.object(rest.PowerMaxRest, 'modify_rdf_device_pair') def test_break_rdf_relationship(self, mock_mod, mock_del, mock_wait): array = self.data.array device_id = self.data.device_id @@ -3781,8 +3780,9 @@ class VMAXProvisionTest(test.TestCase): rdf_group_name, rep_extra_specs, "SyncInProg") mock_wait.assert_called_once() - @mock.patch.object(provision.VMAXProvision, 'disable_group_replication') - @mock.patch.object(provision.VMAXProvision, 'delete_rdf_pair') + @mock.patch.object(provision.PowerMaxProvision, + 'disable_group_replication') + @mock.patch.object(provision.PowerMaxProvision, 'delete_rdf_pair') def test_break_metro_rdf_pair(self, mock_del, mock_disable): self.provision.break_metro_rdf_pair( self.data.array, self.data.device_id, self.data.device_id2, @@ -3799,7 +3799,7 @@ class VMAXProvisionTest(test.TestCase): self.data.rdf_group_no, self.data.device_id2, extra_specs) mock_del_rdf.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'get_storage_group', + @mock.patch.object(rest.PowerMaxRest, 'get_storage_group', return_value=None) def test_create_volume_group_success(self, mock_get_sg): array = self.data.array @@ -3855,9 +3855,9 @@ class VMAXProvisionTest(test.TestCase): target_group_name, snap_name, extra_specs, deleteSnapshot) - @mock.patch.object(rest.VMAXRest, 'get_storage_group', - side_effect=[None, VMAXCommonData.sg_details[1]]) - @mock.patch.object(provision.VMAXProvision, 'create_volume_group') + @mock.patch.object(rest.PowerMaxRest, 'get_storage_group', + side_effect=[None, PowerMaxCommonData.sg_details[1]]) + @mock.patch.object(provision.PowerMaxProvision, 'create_volume_group') def test_get_or_create_volume_group(self, mock_create, mock_sg): for x in range(0, 2): self.provision.get_or_create_volume_group( @@ -3865,8 +3865,8 @@ class VMAXProvisionTest(test.TestCase): self.assertEqual(2, mock_sg.call_count) self.assertEqual(1, mock_create.call_count) - @mock.patch.object(rest.VMAXRest, 'create_resource', - return_value=(202, VMAXCommonData.job_list[0])) + @mock.patch.object(rest.PowerMaxRest, 'create_resource', + return_value=(202, PowerMaxCommonData.job_list[0])) def test_replicate_group(self, mock_create): self.rest.replicate_group( self.data.array, self.data.test_rep_group, @@ -3909,8 +3909,8 @@ class VMAXProvisionTest(test.TestCase): self.data.array, self.data.test_vol_grp_name, self.data.rdf_group_no, 'Failback', self.data.extra_specs) - @mock.patch.object(rest.VMAXRest, 'modify_storagegroup_rdf') - @mock.patch.object(rest.VMAXRest, 'delete_storagegroup_rdf') + @mock.patch.object(rest.PowerMaxRest, 'modify_storagegroup_rdf') + @mock.patch.object(rest.PowerMaxRest, 'delete_storagegroup_rdf') def test_delete_group_replication(self, mock_mod, mock_del): self.provision.delete_group_replication( self.data.array, self.data.test_vol_grp_name, @@ -3919,11 +3919,11 @@ class VMAXProvisionTest(test.TestCase): mock_del.assert_called_once() @mock.patch.object( - rest.VMAXRest, 'get_snap_linked_device_list', - side_effect=[[{'targetDevice': VMAXCommonData.device_id2}], - [{'targetDevice': VMAXCommonData.device_id2}, - {'targetDevice': VMAXCommonData.device_id3}]]) - @mock.patch.object(provision.VMAXProvision, '_unlink_volume') + rest.PowerMaxRest, 'get_snap_linked_device_list', + side_effect=[[{'targetDevice': PowerMaxCommonData.device_id2}], + [{'targetDevice': PowerMaxCommonData.device_id2}, + {'targetDevice': PowerMaxCommonData.device_id3}]]) + @mock.patch.object(provision.PowerMaxProvision, '_unlink_volume') def test_delete_volume_snap_check_for_links(self, mock_unlink, mock_tgts): self.provision.delete_volume_snap_check_for_links( self.data.array, self.data.test_snapshot_snap_name, @@ -3931,7 +3931,7 @@ class VMAXProvisionTest(test.TestCase): mock_unlink.assert_called_once_with( self.data.array, "", "", self.data.test_snapshot_snap_name, self.data.extra_specs, list_volume_pairs=[ - (self.data.device_id, VMAXCommonData.device_id2)], + (self.data.device_id, PowerMaxCommonData.device_id2)], generation=0) mock_unlink.reset_mock() self.provision.delete_volume_snap_check_for_links( @@ -3940,20 +3940,20 @@ class VMAXProvisionTest(test.TestCase): self.assertEqual(2, mock_unlink.call_count) -class VMAXCommonTest(test.TestCase): +class PowerMaxCommonTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXCommonTest, self).setUp() + super(PowerMaxCommonTest, self).setUp() self.mock_object(volume_utils, 'get_max_over_subscription_ratio', return_value=1.0) configuration = FakeConfiguration( None, 'CommonTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_f]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = fc.VMAXFCDriver(configuration=configuration) + driver = fc.PowerMaxFCDriver(configuration=configuration) self.driver = driver self.common = self.driver.common self.masking = self.common.masking @@ -3963,25 +3963,26 @@ class VMAXCommonTest(test.TestCase): self.utils.get_volumetype_extra_specs = ( mock.Mock(return_value=self.data.vol_type_extra_specs)) - @mock.patch.object(rest.VMAXRest, + @mock.patch.object(rest.PowerMaxRest, 'set_rest_credentials') - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_get_slo_workload_combinations', return_value=[]) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, 'get_attributes_from_cinder_config', return_value=[]) def test_gather_info_no_opts(self, mock_parse, mock_combo, mock_rest): configuration = FakeConfiguration(None, 'config_group', None, None) - fc.VMAXFCDriver(configuration=configuration) + fc.PowerMaxFCDriver(configuration=configuration) - @mock.patch.object(rest.VMAXRest, 'is_next_gen_array', + @mock.patch.object(rest.PowerMaxRest, 'is_next_gen_array', return_value=True) - @mock.patch.object(rest.VMAXRest, 'set_rest_credentials') - @mock.patch.object(common.VMAXCommon, '_get_slo_workload_combinations', + @mock.patch.object(rest.PowerMaxRest, 'set_rest_credentials') + @mock.patch.object(common.PowerMaxCommon, '_get_slo_workload_combinations', return_value=[]) - @mock.patch.object(common.VMAXCommon, 'get_attributes_from_cinder_config', - return_value=VMAXCommonData.array_info_wl) + @mock.patch.object(common.PowerMaxCommon, + 'get_attributes_from_cinder_config', + return_value=PowerMaxCommonData.array_info_wl) def test_gather_info_next_gen(self, mock_parse, mock_combo, mock_rest, mock_nextgen): self.common._gather_info() @@ -3993,23 +3994,25 @@ class VMAXCommonTest(test.TestCase): array_info) self.assertTrue(len(finalarrayinfolist) > 1) - @mock.patch.object(rest.VMAXRest, 'get_vmax_model', - return_value=VMAXCommonData.vmax_model_details['model']) - @mock.patch.object(rest.VMAXRest, 'get_slo_list', - return_value=VMAXCommonData.vmax_slo_details['sloId']) + @mock.patch.object(rest.PowerMaxRest, 'get_vmax_model', + return_value=( + PowerMaxCommonData.vmax_model_details['model'])) + @mock.patch.object(rest.PowerMaxRest, 'get_slo_list', + return_value=( + PowerMaxCommonData.vmax_slo_details['sloId'])) def test_get_slo_workload_combinations_vmax(self, mck_slo, mck_model): array_info = self.common.get_attributes_from_cinder_config() finalarrayinfolist = self.common._get_slo_workload_combinations( array_info) self.assertTrue(len(finalarrayinfolist) > 1) - @mock.patch.object(rest.VMAXRest, 'get_vmax_model', - return_value=VMAXCommonData.powermax_model_details[ + @mock.patch.object(rest.PowerMaxRest, 'get_vmax_model', + return_value=PowerMaxCommonData.powermax_model_details[ 'model']) - @mock.patch.object(rest.VMAXRest, 'get_workload_settings', + @mock.patch.object(rest.PowerMaxRest, 'get_workload_settings', return_value=[]) - @mock.patch.object(rest.VMAXRest, 'get_slo_list', - return_value=VMAXCommonData.powermax_slo_details[ + @mock.patch.object(rest.PowerMaxRest, 'get_slo_list', + return_value=PowerMaxCommonData.powermax_slo_details[ 'sloId']) def test_get_slo_workload_combinations_next_gen(self, mck_slo, mck_wl, mck_model): @@ -4018,13 +4021,13 @@ class VMAXCommonTest(test.TestCase): self.data.array_info_no_wl) self.assertTrue(len(finalarrayinfolist) == 14) - @mock.patch.object(rest.VMAXRest, 'get_vmax_model', - return_value=VMAXCommonData.vmax_model_details[ + @mock.patch.object(rest.PowerMaxRest, 'get_vmax_model', + return_value=PowerMaxCommonData.vmax_model_details[ 'model']) - @mock.patch.object(rest.VMAXRest, 'get_workload_settings', + @mock.patch.object(rest.PowerMaxRest, 'get_workload_settings', return_value=[]) - @mock.patch.object(rest.VMAXRest, 'get_slo_list', - return_value=VMAXCommonData.powermax_slo_details[ + @mock.patch.object(rest.PowerMaxRest, 'get_slo_list', + return_value=PowerMaxCommonData.powermax_slo_details[ 'sloId']) def test_get_slo_workload_combinations_next_gen_vmax( self, mck_slo, mck_wl, mck_model): @@ -4115,9 +4118,9 @@ class VMAXCommonTest(test.TestCase): self.data.test_legacy_vol) mock_del.assert_called_once_with(self.data.test_legacy_snapshot) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'return_volume_to_fast_managed_group') - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_remove_members(self, mock_rm, mock_return): array = self.data.array device_id = self.data.device_id @@ -4130,9 +4133,9 @@ class VMAXCommonTest(test.TestCase): array, volume, device_id, volume_name, extra_specs, True, self.data.connector, async_grp=None) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'return_volume_to_fast_managed_group') - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_remove_members_multiattach_case(self, mock_rm, mock_return): array = self.data.array device_id = self.data.device_id @@ -4159,7 +4162,7 @@ class VMAXCommonTest(test.TestCase): array, volume, device_id, extra_specs, connector, False, async_grp=None) - @mock.patch.object(common.VMAXCommon, '_remove_members') + @mock.patch.object(common.PowerMaxCommon, '_remove_members') def test_unmap_lun_attachments(self, mock_rm): volume1 = deepcopy(self.data.test_volume) volume1.volume_attachment.objects = [self.data.test_volume_attachment] @@ -4239,10 +4242,10 @@ class VMAXCommonTest(test.TestCase): connector) self.assertEqual(ref_dict, device_info_dict) - @mock.patch.object(common.VMAXCommon, 'find_host_lun_id', + @mock.patch.object(common.PowerMaxCommon, 'find_host_lun_id', return_value=({}, False)) - @mock.patch.object(common.VMAXCommon, '_attach_volume', - return_value=({}, VMAXCommonData.port_group_name_f)) + @mock.patch.object(common.PowerMaxCommon, '_attach_volume', + return_value=({}, PowerMaxCommonData.port_group_name_f)) def test_initialize_connection_not_mapped(self, mock_attach, mock_id): volume = self.data.test_volume connector = self.data.connector @@ -4257,12 +4260,12 @@ class VMAXCommonTest(test.TestCase): mock_attach.assert_called_once_with( volume, connector, extra_specs, masking_view_dict) - @mock.patch.object(rest.VMAXRest, 'is_next_gen_array', + @mock.patch.object(rest.PowerMaxRest, 'is_next_gen_array', return_value=True) - @mock.patch.object(common.VMAXCommon, 'find_host_lun_id', + @mock.patch.object(common.PowerMaxCommon, 'find_host_lun_id', return_value=({}, False)) - @mock.patch.object(common.VMAXCommon, '_attach_volume', - return_value=({}, VMAXCommonData.port_group_name_f)) + @mock.patch.object(common.PowerMaxCommon, '_attach_volume', + return_value=({}, PowerMaxCommonData.port_group_name_f)) def test_initialize_connection_not_mapped_next_gen(self, mock_attach, mock_id, mck_gen): volume = self.data.test_volume @@ -4272,12 +4275,12 @@ class VMAXCommonTest(test.TestCase): self.assertEqual({}, device_info_dict) @mock.patch.object( - masking.VMAXMasking, 'pre_multiattach', - return_value=VMAXCommonData.masking_view_dict_multiattach) - @mock.patch.object(common.VMAXCommon, 'find_host_lun_id', + masking.PowerMaxMasking, 'pre_multiattach', + return_value=PowerMaxCommonData.masking_view_dict_multiattach) + @mock.patch.object(common.PowerMaxCommon, 'find_host_lun_id', return_value=({}, True)) - @mock.patch.object(common.VMAXCommon, '_attach_volume', - return_value=({}, VMAXCommonData.port_group_name_f)) + @mock.patch.object(common.PowerMaxCommon, '_attach_volume', + return_value=({}, PowerMaxCommonData.port_group_name_f)) def test_initialize_connection_multiattach_case( self, mock_attach, mock_id, mock_pre): volume = self.data.test_volume @@ -4307,11 +4310,11 @@ class VMAXCommonTest(test.TestCase): volume, connector, extra_specs, masking_view_dict) self.assertEqual(ref_dict, device_info_dict) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'check_if_rollback_action_for_masking_required') - @mock.patch.object(masking.VMAXMasking, 'setup_masking_view', + @mock.patch.object(masking.PowerMaxMasking, 'setup_masking_view', return_value={}) - @mock.patch.object(common.VMAXCommon, 'find_host_lun_id', + @mock.patch.object(common.PowerMaxCommon, 'find_host_lun_id', return_value=({}, False)) def test_attach_volume_failed(self, mock_lun, mock_setup, mock_rollback): volume = self.data.test_volume @@ -4336,9 +4339,10 @@ class VMAXCommonTest(test.TestCase): self.common._unmap_lun.assert_called_once_with( volume, connector) - @mock.patch.object(rest.VMAXRest, 'is_next_gen_array', return_value=True) - @mock.patch.object(common.VMAXCommon, '_sync_check') - @mock.patch.object(provision.VMAXProvision, 'extend_volume') + @mock.patch.object(rest.PowerMaxRest, 'is_next_gen_array', + return_value=True) + @mock.patch.object(common.PowerMaxCommon, '_sync_check') + @mock.patch.object(provision.PowerMaxProvision, 'extend_volume') def test_extend_volume_success(self, mock_extend, mock_sync, mock_newgen): volume = self.data.test_volume array = self.data.array @@ -4452,8 +4456,8 @@ class VMAXCommonTest(test.TestCase): self.assertEqual({}, maskedvols) @mock.patch.object( - common.VMAXCommon, '_get_masking_views_from_volume', - return_value=([], [VMAXCommonData.masking_view_name_f])) + common.PowerMaxCommon, '_get_masking_views_from_volume', + return_value=([], [PowerMaxCommonData.masking_view_name_f])) def test_find_host_lun_id_multiattach(self, mock_mask): volume = self.data.test_volume extra_specs = self.data.extra_specs @@ -4461,8 +4465,8 @@ class VMAXCommonTest(test.TestCase): volume, 'HostX', extra_specs) self.assertTrue(is_multiattach) - @mock.patch.object(common.VMAXCommon, 'get_remote_target_device', - return_value=VMAXCommonData.device_id2) + @mock.patch.object(common.PowerMaxCommon, 'get_remote_target_device', + return_value=PowerMaxCommonData.device_id2) def test_find_host_lun_id_rep_extra_specs(self, mock_tgt): self.common.find_host_lun_id( self.data.test_volume, 'HostX', @@ -4520,8 +4524,8 @@ class VMAXCommonTest(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.common._initial_setup, volume) - @mock.patch.object(common.VMAXCommon, 'get_remote_target_device', - return_value=VMAXCommonData.device_id2) + @mock.patch.object(common.PowerMaxCommon, 'get_remote_target_device', + return_value=PowerMaxCommonData.device_id2) def test_populate_masking_dict(self, mock_tgt): volume = self.data.test_volume connector = self.data.connector @@ -4673,7 +4677,8 @@ class VMAXCommonTest(test.TestCase): self.common._create_snapshot, array, snapshot, source_device_id, extra_specs) - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') def test_delete_volume_from_srp(self, mock_rm): array = self.data.array device_id = self.data.device_id @@ -4847,7 +4852,7 @@ class VMAXCommonTest(test.TestCase): assert_called_once_with( array, device_id, volume_name, extra_specs)) - @mock.patch.object(utils.VMAXUtils, 'is_replication_enabled', + @mock.patch.object(utils.PowerMaxUtils, 'is_replication_enabled', side_effect=[False, True]) def test_remove_vol_and_cleanup_replication(self, mock_rep_enabled): array = self.data.array @@ -4869,10 +4874,10 @@ class VMAXCommonTest(test.TestCase): mock_clean.assert_called_once_with( volume, volume_name, device_id, extra_specs) - @mock.patch.object(utils.VMAXUtils, 'is_volume_failed_over', + @mock.patch.object(utils.PowerMaxUtils, 'is_volume_failed_over', side_effect=[True, False]) - @mock.patch.object(common.VMAXCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.rep_extra_specs) + @mock.patch.object(common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=PowerMaxCommonData.rep_extra_specs) def test_get_target_wwns_from_masking_view(self, mock_rep_specs, mock_fo): ref_wwns = [self.data.wwnn1] for x in range(0, 2): @@ -4889,11 +4894,11 @@ class VMAXCommonTest(test.TestCase): self.data.extra_specs) self.assertEqual([], target_wwns) - @mock.patch.object(common.VMAXCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.rep_extra_specs) - @mock.patch.object(common.VMAXCommon, 'get_remote_target_device', - return_value=(VMAXCommonData.device_id2,)) - @mock.patch.object(utils.VMAXUtils, 'is_metro_device', + @mock.patch.object(common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=PowerMaxCommonData.rep_extra_specs) + @mock.patch.object(common.PowerMaxCommon, 'get_remote_target_device', + return_value=(PowerMaxCommonData.device_id2,)) + @mock.patch.object(utils.PowerMaxUtils, 'is_metro_device', side_effect=[False, True]) def test_get_target_wwns(self, mock_metro, mock_tgt, mock_specs): __, metro_wwns = self.common.get_target_wwns_from_masking_view( @@ -5005,7 +5010,7 @@ class VMAXCommonTest(test.TestCase): self.common._cleanup_target.assert_not_called() @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, 'remove_and_reset_members') def test_cleanup_target_sync_present(self, mock_remove): array = self.data.array @@ -5048,10 +5053,10 @@ class VMAXCommonTest(test.TestCase): extra_specs) @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'delete_volume_snap') @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_sync_check_temp_snap(self, mock_break, mock_delete): array = self.data.array @@ -5086,10 +5091,10 @@ class VMAXCommonTest(test.TestCase): array, snap_name2, device_id, restored=False, generation=0) @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'delete_volume_snap') @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_sync_check_not_temp_snap(self, mock_break, mock_delete): array = self.data.array @@ -5110,7 +5115,7 @@ class VMAXCommonTest(test.TestCase): mock_delete.assert_not_called() @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_sync_check_no_sessions(self, mock_break): array = self.data.array @@ -5124,10 +5129,10 @@ class VMAXCommonTest(test.TestCase): mock_break.assert_not_called() @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'delete_volume_snap') @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_clone_check_cinder_snap(self, mock_break, mock_delete): array = self.data.array @@ -5152,10 +5157,10 @@ class VMAXCommonTest(test.TestCase): array, target, device_id, snap_name, extra_specs, 0) @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'delete_volume_snap') @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_clone_check_temp_snap(self, mock_break, mock_delete): array = self.data.array @@ -5186,7 +5191,7 @@ class VMAXCommonTest(test.TestCase): mock_delete.asset_not_called() @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'break_replication_relationship') def test_clone_check_no_sessions(self, mock_break): array = self.data.array @@ -5209,10 +5214,10 @@ class VMAXCommonTest(test.TestCase): self.assertEqual(ref_update, model_update) @mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', + rest.PowerMaxRest, 'get_masking_views_from_storage_group', return_value=None) @mock.patch.object( - rest.VMAXRest, 'is_vol_in_rep_session', + rest.PowerMaxRest, 'is_vol_in_rep_session', return_value=(False, False, None)) def test_check_lun_valid_for_cinder_management(self, mock_rep, mock_mv): external_ref = {u'source-name': u'00003'} @@ -5223,10 +5228,10 @@ class VMAXCommonTest(test.TestCase): self.assertIsNone(source_sg) @mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', + rest.PowerMaxRest, 'get_masking_views_from_storage_group', return_value=None) @mock.patch.object( - rest.VMAXRest, 'is_vol_in_rep_session', + rest.PowerMaxRest, 'is_vol_in_rep_session', return_value=(False, False, None)) def test_check_lun_valid_for_cinder_management_multiple_sg_exception( self, mock_rep, mock_mv): @@ -5238,19 +5243,20 @@ class VMAXCommonTest(test.TestCase): self.data.test_volume.id, external_ref) @mock.patch.object( - rest.VMAXRest, 'get_volume', + rest.PowerMaxRest, 'get_volume', side_effect=[ None, - VMAXCommonData.volume_details[2], - VMAXCommonData.volume_details[2], - VMAXCommonData.volume_details[1]]) + PowerMaxCommonData.volume_details[2], + PowerMaxCommonData.volume_details[2], + PowerMaxCommonData.volume_details[1]]) @mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', - side_effect=[VMAXCommonData.sg_details[1]['maskingview'], + rest.PowerMaxRest, 'get_masking_views_from_storage_group', + side_effect=[PowerMaxCommonData.sg_details[1]['maskingview'], None]) - @mock.patch.object(rest.VMAXRest, 'get_storage_groups_from_volume', - return_value=[VMAXCommonData.defaultstoragegroup_name]) - @mock.patch.object(rest.VMAXRest, 'is_vol_in_rep_session', + @mock.patch.object(rest.PowerMaxRest, 'get_storage_groups_from_volume', + return_value=( + [PowerMaxCommonData.defaultstoragegroup_name])) + @mock.patch.object(rest.PowerMaxRest, 'is_vol_in_rep_session', side_effect=[(True, False, []), (False, False, None)]) def test_check_lun_valid_for_cinder_management_exception( self, mock_rep, mock_sg, mock_mvs, mock_get_vol): @@ -5280,7 +5286,7 @@ class VMAXCommonTest(test.TestCase): self.common.manage_existing_get_size, self.data.test_volume, external_ref) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_remove_vol_and_cleanup_replication') def test_unmanage_success(self, mock_rm): volume = self.data.test_volume @@ -5307,7 +5313,7 @@ class VMAXCommonTest(test.TestCase): self.common.unmanage(volume) self.rest.rename_volume.assert_not_called() - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_slo_workload_migration') def test_retype(self, mock_migrate): device_id = self.data.device_id @@ -5390,7 +5396,7 @@ class VMAXCommonTest(test.TestCase): extra_specs[utils.SRP], self.data.slo, self.data.workload, volume_name, new_type, extra_specs) - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_migrate_volume_success(self, mock_remove): with mock.patch.object(self.rest, 'is_volume_in_storagegroup', return_value=True): @@ -5422,7 +5428,7 @@ class VMAXCommonTest(test.TestCase): self.assertTrue(migrate_status) mock_remove.assert_not_called() - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_migrate_volume_failed_get_new_sg_failed(self, mock_remove): device_id = self.data.device_id volume_name = self.data.test_volume.name @@ -5606,7 +5612,7 @@ class VMAXCommonTest(test.TestCase): model_update = self.common.create_group(None, self.data.test_group_1) self.assertEqual(ref_model_update, model_update) - @mock.patch.object(provision.VMAXProvision, 'create_volume_group', + @mock.patch.object(provision.PowerMaxProvision, 'create_volume_group', side_effect=exception.CinderException) @mock.patch.object(volume_utils, 'is_group_a_type', return_value=False) def test_create_group_exception(self, mock_type, mock_create): @@ -5668,7 +5674,7 @@ class VMAXCommonTest(test.TestCase): remove_vols) self.assertEqual(ref_model_update, model_update) - @mock.patch.object(common.VMAXCommon, '_find_volume_group', + @mock.patch.object(common.PowerMaxCommon, '_find_volume_group', return_value=None) @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=True) @@ -5676,7 +5682,7 @@ class VMAXCommonTest(test.TestCase): self.assertRaises(exception.GroupNotFound, self.common.update_group, self.data.test_group_1, [], []) - @mock.patch.object(common.VMAXCommon, '_find_volume_group', + @mock.patch.object(common.PowerMaxCommon, '_find_volume_group', side_effect=exception.VolumeBackendAPIException) @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=True) @@ -5735,9 +5741,9 @@ class VMAXCommonTest(test.TestCase): self.assertEqual(ref_model_update, model_update) @mock.patch.object( - common.VMAXCommon, '_get_clone_vol_info', - return_value=(VMAXCommonData.device_id, - VMAXCommonData.extra_specs, 1, 'tgt_vol')) + common.PowerMaxCommon, '_get_clone_vol_info', + return_value=(PowerMaxCommonData.device_id, + PowerMaxCommonData.extra_specs, 1, 'tgt_vol')) @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=True) @mock.patch.object(volume_utils, 'is_group_a_type', @@ -5752,9 +5758,9 @@ class VMAXCommonTest(test.TestCase): self.assertEqual(ref_model_update, model_update) @mock.patch.object( - common.VMAXCommon, '_remove_vol_and_cleanup_replication') + common.PowerMaxCommon, '_remove_vol_and_cleanup_replication') @mock.patch.object( - masking.VMAXMasking, 'remove_volumes_from_storage_group') + masking.PowerMaxMasking, 'remove_volumes_from_storage_group') def test_rollback_create_group_from_src( self, mock_rm, mock_clean): rollback_dict = { @@ -5887,7 +5893,7 @@ class VMAXCommonTest(test.TestCase): conf_returned = self.common.get_attributes_from_cinder_config() self.assertFalse(conf_returned['SSLVerify']) - @mock.patch.object(rest.VMAXRest, + @mock.patch.object(rest.PowerMaxRest, 'get_size_of_device_on_array', return_value=2.0) def test_manage_snapshot_get_size_success(self, mock_get_size): @@ -5895,7 +5901,7 @@ class VMAXCommonTest(test.TestCase): self.data.test_snapshot) self.assertEqual(2, size) - @mock.patch.object(rest.VMAXRest, 'get_volume_snap', + @mock.patch.object(rest.PowerMaxRest, 'get_volume_snap', return_value={'snap_name': 'snap_name'}) def test_manage_snapshot_success(self, mock_snap): snapshot = self.data.test_snapshot_manage @@ -5920,7 +5926,7 @@ class VMAXCommonTest(test.TestCase): self.common.manage_existing_snapshot, snapshot, existing_ref) - @mock.patch.object(utils.VMAXUtils, + @mock.patch.object(utils.PowerMaxUtils, 'is_volume_failed_over', return_value=True) def test_manage_snapshot_fail_vol_failed_over(self, mock_failed): @@ -5930,7 +5936,8 @@ class VMAXCommonTest(test.TestCase): self.common.manage_existing_snapshot, snapshot, existing_ref) - @mock.patch.object(rest.VMAXRest, 'get_volume_snap', return_value=False) + @mock.patch.object(rest.PowerMaxRest, 'get_volume_snap', + return_value=False) def test_manage_snapshot_fail_vol_not_snap_src(self, mock_snap): snapshot = self.data.test_snapshot_manage existing_ref = {u'source-name': u'test_snap'} @@ -5938,7 +5945,7 @@ class VMAXCommonTest(test.TestCase): self.common.manage_existing_snapshot, snapshot, existing_ref) - @mock.patch.object(utils.VMAXUtils, 'modify_snapshot_prefix', + @mock.patch.object(utils.PowerMaxUtils, 'modify_snapshot_prefix', side_effect=exception.VolumeBackendAPIException) def test_manage_snapshot_fail_add_prefix(self, mock_mod): snapshot = self.data.test_snapshot_manage @@ -5947,20 +5954,20 @@ class VMAXCommonTest(test.TestCase): self.common.manage_existing_snapshot, snapshot, existing_ref) - @mock.patch.object(common.VMAXCommon, '_sync_check') - @mock.patch.object(rest.VMAXRest, 'modify_volume_snap') + @mock.patch.object(common.PowerMaxCommon, '_sync_check') + @mock.patch.object(rest.PowerMaxRest, 'modify_volume_snap') def test_unmanage_snapshot_success(self, mock_mod, mock_sync): self.common.unmanage_snapshot(self.data.test_snapshot_manage) mock_mod.assert_called_once() @mock.patch.object( - utils.VMAXUtils, 'is_volume_failed_over', return_value=True) + utils.PowerMaxUtils, 'is_volume_failed_over', return_value=True) def test_unmanage_snapshot_fail_failover(self, mock_failed): self.assertRaises(exception.VolumeBackendAPIException, self.common.unmanage_snapshot, self.data.test_snapshot_manage) - @mock.patch.object(rest.VMAXRest, + @mock.patch.object(rest.PowerMaxRest, 'modify_volume_snap', side_effect=exception.VolumeBackendAPIException) def test_unmanage_snapshot_fail_rename(self, mock_snap): @@ -5968,10 +5975,10 @@ class VMAXCommonTest(test.TestCase): self.common.unmanage_snapshot, self.data.test_snapshot_manage) - @mock.patch.object(provision.VMAXProvision, 'is_restore_complete', + @mock.patch.object(provision.PowerMaxProvision, 'is_restore_complete', return_value=True) - @mock.patch.object(common.VMAXCommon, '_sync_check') - @mock.patch.object(provision.VMAXProvision, + @mock.patch.object(common.PowerMaxCommon, '_sync_check') + @mock.patch.object(provision.PowerMaxProvision, 'revert_volume_snapshot') def test_revert_to_snapshot(self, mock_revert, mock_sync, mock_complete): volume = self.data.test_volume @@ -5986,7 +5993,7 @@ class VMAXCommonTest(test.TestCase): mock_revert.assert_called_once_with( array, device_id, snap_name, extra_specs) - @mock.patch.object(utils.VMAXUtils, 'is_replication_enabled', + @mock.patch.object(utils.PowerMaxUtils, 'is_replication_enabled', return_value=True) def test_revert_to_snapshot_replicated(self, mock_rep): volume = self.data.test_volume @@ -6181,29 +6188,29 @@ class VMAXCommonTest(test.TestCase): self.common.update_volume_stats() self.common.retest_primary_u4p.assert_not_called() - @mock.patch.object(rest.VMAXRest, 'request', + @mock.patch.object(rest.PowerMaxRest, 'request', return_value=[200, None]) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, 'get_attributes_from_cinder_config', - return_value=VMAXCommonData.u4p_failover_target[0]) + return_value=PowerMaxCommonData.u4p_failover_target[0]) def test_retest_primary_u4p(self, mock_primary_u4p, mock_request): self.common.retest_primary_u4p() self.assertFalse(self.rest.u4p_in_failover) -class VMAXFCTest(test.TestCase): +class PowerMaxFCTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXFCTest, self).setUp() + super(PowerMaxFCTest, self).setUp() volume_utils.get_max_over_subscription_ratio = mock.Mock() self.configuration = FakeConfiguration( None, 'FCTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = fc.VMAXFCDriver(configuration=self.configuration) + driver = fc.PowerMaxFCDriver(configuration=self.configuration) self.driver = driver self.common = self.driver.common self.masking = self.common.masking @@ -6312,8 +6319,8 @@ class VMAXFCTest(test.TestCase): self.assertEqual({}, zoning_mappings) @mock.patch.object( - common.VMAXCommon, 'get_masking_views_from_volume', - return_value=([VMAXCommonData.masking_view_name_f], True)) + common.PowerMaxCommon, 'get_masking_views_from_volume', + return_value=([PowerMaxCommonData.masking_view_name_f], True)) def test_get_zoning_mappings_metro(self, mock_mv): ref_mappings = self.data.zoning_mappings_metro zoning_mappings = self.driver._get_zoning_mappings( @@ -6342,7 +6349,7 @@ class VMAXFCTest(test.TestCase): '123456789054321': ['123450987654321']} with mock.patch.object(fczm_utils, 'create_lookup_service', return_value=FakeLookupService()): - driver = fc.VMAXFCDriver(configuration=self.configuration) + driver = fc.PowerMaxFCDriver(configuration=self.configuration) with mock.patch.object(driver.common, 'get_target_wwns_from_masking_view', return_value=(self.data.target_wwns, [])): @@ -6449,18 +6456,18 @@ class VMAXFCTest(test.TestCase): mock_fo.assert_called_once() -class VMAXISCSITest(test.TestCase): +class PowerMaxISCSITest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXISCSITest, self).setUp() + super(PowerMaxISCSITest, self).setUp() configuration = FakeConfiguration( None, 'ISCSITests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i]) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = iscsi.VMAXISCSIDriver(configuration=configuration) + driver = iscsi.PowerMaxISCSIDriver(configuration=configuration) self.driver = driver self.common = self.driver.common self.masking = self.common.masking @@ -6756,24 +6763,24 @@ class VMAXISCSITest(test.TestCase): mock_fo.assert_called_once() -class VMAXMaskingTest(test.TestCase): +class PowerMaxMaskingTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXMaskingTest, self).setUp() + super(PowerMaxMaskingTest, self).setUp() volume_utils.get_max_over_subscription_ratio = mock.Mock() configuration = mock.Mock() configuration.safe_get.return_value = 'MaskingTests' configuration.config_group = 'MaskingTests' - self._gather_info = common.VMAXCommon._gather_info - common.VMAXCommon._get_u4p_failover_info = mock.Mock() - common.VMAXCommon._gather_info = mock.Mock() - rest.VMAXRest._establish_rest_session = mock.Mock( + self._gather_info = common.PowerMaxCommon._gather_info + common.PowerMaxCommon._get_u4p_failover_info = mock.Mock() + common.PowerMaxCommon._gather_info = mock.Mock() + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = common.VMAXCommon( + driver = common.PowerMaxCommon( 'iSCSI', self.data.version, configuration=configuration) - driver_fc = common.VMAXCommon( + driver_fc = common.PowerMaxCommon( 'FC', self.data.version, configuration=configuration) self.driver = driver self.driver_fc = driver_fc @@ -6788,11 +6795,11 @@ class VMAXMaskingTest(test.TestCase): self.volume_name = self.data.volume_details[0]['volume_identifier'] def tearDown(self): - super(VMAXMaskingTest, self).tearDown() - common.VMAXCommon._gather_info = self._gather_info + super(PowerMaxMaskingTest, self).tearDown() + common.PowerMaxCommon._gather_info = self._gather_info @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, 'get_or_create_masking_view_and_map_lun') def test_setup_masking_view(self, mock_get_or_create_mv): self.driver.masking.setup_masking_view( @@ -6801,21 +6808,21 @@ class VMAXMaskingTest(test.TestCase): mock_get_or_create_mv.assert_called_once() @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_adding_volume_to_storage_group') @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_move_vol_from_default_sg', return_value=None) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_get_or_create_masking_view', side_effect=[None, "Error in masking view retrieval", exception.VolumeBackendAPIException]) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_element_from_masking_view', - side_effect=[VMAXCommonData.port_group_name_i, + side_effect=[PowerMaxCommonData.port_group_name_i, Exception('Exception')]) def test_get_or_create_masking_view_and_map_lun( self, mock_masking_view_element, mock_masking, mock_move, @@ -6841,15 +6848,15 @@ class VMAXMaskingTest(test.TestCase): self.maskingviewdict, self.extra_specs) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_adding_volume_to_storage_group', return_value=None) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'move_volume_between_storage_groups', side_effect=[None, exception.VolumeBackendAPIException(data='')]) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'is_volume_in_storagegroup', side_effect=[True, False, True]) def test_move_vol_from_default_sg( @@ -6869,11 +6876,11 @@ class VMAXMaskingTest(test.TestCase): self.data.storagegroup_name_i, self.extra_specs) self.assertIsNotNone(msg) - @mock.patch.object(rest.VMAXRest, 'remove_child_sg_from_parent_sg') - @mock.patch.object(masking.VMAXMasking, 'get_parent_sg_from_child', - side_effect=[None, VMAXCommonData.parent_sg_f]) + @mock.patch.object(rest.PowerMaxRest, 'remove_child_sg_from_parent_sg') + @mock.patch.object(masking.PowerMaxMasking, 'get_parent_sg_from_child', + side_effect=[None, PowerMaxCommonData.parent_sg_f]) @mock.patch.object( - rest.VMAXRest, 'get_num_vols_in_sg', side_effect=[2, 1, 1]) + rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[2, 1, 1]) def test_move_volume_between_storage_groups( self, mock_num, mock_parent, mock_rm): for x in range(0, 3): @@ -6884,17 +6891,17 @@ class VMAXMaskingTest(test.TestCase): mock_rm.assert_called_once() @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_masking_view', - side_effect=[VMAXCommonData.maskingview, - VMAXCommonData.maskingview, None]) + side_effect=[PowerMaxCommonData.maskingview, + PowerMaxCommonData.maskingview, None]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_validate_existing_masking_view', - side_effect=[(VMAXCommonData.maskingview[1]['storageGroupId'], + side_effect=[(PowerMaxCommonData.maskingview[1]['storageGroupId'], None), (None, "Error Message")]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_create_new_masking_view', return_value=None) def test_get_or_create_masking_view( @@ -6907,27 +6914,27 @@ class VMAXMaskingTest(test.TestCase): mock_create_mv.assert_called_once() @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_get_or_create_storage_group', side_effect=["Storage group not found", None, "Storage group not found", None, None, None, None, None, None, None, None]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_port_group', side_effect=[(None, "Port group error"), (None, None), (None, None), (None, None)]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_get_or_create_initiator_group', side_effect=[(None, "Initiator group error"), (None, None), (None, None)]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_move_vol_from_default_sg', side_effect=["Storage group error", None]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, 'create_masking_view', return_value=None) def test_create_new_masking_view( @@ -6941,23 +6948,23 @@ class VMAXMaskingTest(test.TestCase): mock_create_mv.assert_called_once() @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_existing_storage_group', - side_effect=[(VMAXCommonData.storagegroup_name_i, None), - (VMAXCommonData.storagegroup_name_i, None), + side_effect=[(PowerMaxCommonData.storagegroup_name_i, None), + (PowerMaxCommonData.storagegroup_name_i, None), (None, "Error Checking existing storage group")]) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_element_from_masking_view', - return_value=VMAXCommonData.port_group_name_i) + return_value=PowerMaxCommonData.port_group_name_i) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_port_group', side_effect=[(None, None), (None, "Error checking pg")]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_existing_initiator_group', - return_value=(VMAXCommonData.initiatorgroup_name_i, None)) + return_value=(PowerMaxCommonData.initiatorgroup_name_i, None)) def test_validate_existing_masking_view( self, mock_check_ig, mock_check_pg, mock_get_mv_element, mock_check_sg): @@ -6973,13 +6980,13 @@ class VMAXMaskingTest(test.TestCase): mock_check_ig.assert_called_once() @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_storage_group', - side_effect=[VMAXCommonData.storagegroup_name_i, None, None]) + side_effect=[PowerMaxCommonData.storagegroup_name_i, None, None]) @mock.patch.object( - provision.VMAXProvision, + provision.PowerMaxProvision, 'create_storage_group', - side_effect=[VMAXCommonData.storagegroup_name_i, None]) + side_effect=[PowerMaxCommonData.storagegroup_name_i, None]) def test_get_or_create_storage_group(self, mock_sg, mock_get_sg): for x in range(0, 2): self.driver.masking._get_or_create_storage_group( @@ -6992,23 +6999,23 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(2, mock_sg.call_count) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_move_vol_from_default_sg', return_value=None) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_get_or_create_storage_group', return_value=None) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_element_from_masking_view', - return_value=VMAXCommonData.parent_sg_i) + return_value=PowerMaxCommonData.parent_sg_i) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'is_child_sg_in_parent_sg', side_effect=[True, False]) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_check_add_child_sg_to_parent_sg', return_value=None) def test_check_existing_storage_group_success( @@ -7018,8 +7025,8 @@ class VMAXMaskingTest(test.TestCase): masking_view_dict['extra_specs'] = self.data.extra_specs with mock.patch.object(self.driver.rest, 'get_storage_group', side_effect=[ - VMAXCommonData.parent_sg_i, - VMAXCommonData.storagegroup_name_i]): + PowerMaxCommonData.parent_sg_i, + PowerMaxCommonData.storagegroup_name_i]): _, msg = ( self.driver.masking._check_existing_storage_group( self.data.array, self.maskingviewdict['maskingview_name'], @@ -7028,7 +7035,7 @@ class VMAXMaskingTest(test.TestCase): mock_create_sg.assert_not_called() with mock.patch.object(self.driver.rest, 'get_storage_group', side_effect=[ - VMAXCommonData.parent_sg_i, None]): + PowerMaxCommonData.parent_sg_i, None]): _, msg = ( self.driver.masking._check_existing_storage_group( self.data.array, self.maskingviewdict['maskingview_name'], @@ -7036,27 +7043,27 @@ class VMAXMaskingTest(test.TestCase): self.assertIsNone(msg) mock_create_sg.assert_called_once_with( self.data.array, masking_view_dict, - VMAXCommonData.storagegroup_name_f, + PowerMaxCommonData.storagegroup_name_f, self.data.extra_specs) @mock.patch.object( - masking.VMAXMasking, + masking.PowerMaxMasking, '_move_vol_from_default_sg', side_effect=[None, "Error Message"]) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'is_child_sg_in_parent_sg', side_effect=[True, False, False]) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_element_from_masking_view', - return_value=VMAXCommonData.parent_sg_i) + return_value=PowerMaxCommonData.parent_sg_i) @mock.patch.object( - rest.VMAXRest, + rest.PowerMaxRest, 'get_storage_group', - side_effect=[None, VMAXCommonData.parent_sg_i, None, - VMAXCommonData.parent_sg_i, None, - VMAXCommonData.parent_sg_i, None]) + side_effect=[None, PowerMaxCommonData.parent_sg_i, None, + PowerMaxCommonData.parent_sg_i, None, + PowerMaxCommonData.parent_sg_i, None]) def test_check_existing_storage_group_failed( self, mock_get_sg, mock_get_mv_element, mock_child, mock_move): masking_view_dict = deepcopy(self.data.masking_view_dict) @@ -7070,8 +7077,9 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(7, mock_get_sg.call_count) self.assertEqual(1, mock_move.call_count) - @mock.patch.object(rest.VMAXRest, 'get_portgroup', - side_effect=[VMAXCommonData.port_group_name_i, None]) + @mock.patch.object(rest.PowerMaxRest, 'get_portgroup', + side_effect=( + [PowerMaxCommonData.port_group_name_i, None])) def test_check_port_group( self, mock_get_pg): for x in range(0, 2): @@ -7081,11 +7089,12 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(2, mock_get_pg.call_count) @mock.patch.object( - masking.VMAXMasking, '_find_initiator_group', - side_effect=[VMAXCommonData.initiatorgroup_name_i, None, None]) - @mock.patch.object(masking.VMAXMasking, '_create_initiator_group', - side_effect=[VMAXCommonData.initiatorgroup_name_i, None] - ) + masking.PowerMaxMasking, '_find_initiator_group', + side_effect=[PowerMaxCommonData.initiatorgroup_name_i, None, None]) + @mock.patch.object(masking.PowerMaxMasking, '_create_initiator_group', + side_effect=( + [PowerMaxCommonData.initiatorgroup_name_i, + None])) def test_get_or_create_initiator_group(self, mock_create_ig, mock_find_ig): self.driver.masking._get_or_create_initiator_group( self.data.array, self.data.initiatorgroup_name_i, @@ -7104,8 +7113,8 @@ class VMAXMaskingTest(test.TestCase): def test_check_existing_initiator_group(self): with mock.patch.object( - rest.VMAXRest, 'get_element_from_masking_view', - return_value=VMAXCommonData.inititiatorgroup): + rest.PowerMaxRest, 'get_element_from_masking_view', + return_value=PowerMaxCommonData.inititiatorgroup): ig_from_mv, msg = ( self.driver.masking._check_existing_initiator_group( self.data.array, self.maskingviewdict['maskingview_name'], @@ -7115,9 +7124,9 @@ class VMAXMaskingTest(test.TestCase): def test_check_adding_volume_to_storage_group(self): with mock.patch.object( - masking.VMAXMasking, '_create_initiator_group'): + masking.PowerMaxMasking, '_create_initiator_group'): with mock.patch.object( - rest.VMAXRest, 'is_volume_in_storagegroup', + rest.PowerMaxRest, 'is_volume_in_storagegroup', side_effect=[True, False]): msg = ( self.driver.masking._check_adding_volume_to_storage_group( @@ -7133,17 +7142,17 @@ class VMAXMaskingTest(test.TestCase): self.maskingviewdict[utils.VOL_NAME], self.maskingviewdict[utils.EXTRA_SPECS])) - @mock.patch.object(rest.VMAXRest, 'add_vol_to_sg') + @mock.patch.object(rest.PowerMaxRest, 'add_vol_to_sg') def test_add_volume_to_storage_group(self, mock_add_volume): self.driver.masking.add_volume_to_storage_group( self.data.array, self.device_id, self.data.storagegroup_name_i, self.volume_name, self.extra_specs) mock_add_volume.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'remove_vol_from_sg') + @mock.patch.object(rest.PowerMaxRest, 'remove_vol_from_sg') def test_remove_vol_from_storage_group(self, mock_remove_volume): with mock.patch.object( - rest.VMAXRest, 'is_volume_in_storagegroup', + rest.PowerMaxRest, 'is_volume_in_storagegroup', side_effect=[False, True]): self.driver.masking.remove_vol_from_storage_group( self.data.array, self.device_id, self.data.storagegroup_name_i, @@ -7174,10 +7183,10 @@ class VMAXMaskingTest(test.TestCase): def test_find_initiator_group_found(self): with mock.patch.object( - rest.VMAXRest, 'get_initiator_list', + rest.PowerMaxRest, 'get_initiator_list', return_value=self.data.initiator_list[2]['initiatorId']): with mock.patch.object( - rest.VMAXRest, 'get_initiator_group_from_initiator', + rest.PowerMaxRest, 'get_initiator_group_from_initiator', return_value=self.data.initiator_list): found_init_group_nam = ( self.driver.masking._find_initiator_group( @@ -7187,10 +7196,10 @@ class VMAXMaskingTest(test.TestCase): def test_find_initiator_group_not_found(self): with mock.patch.object( - rest.VMAXRest, 'get_initiator_list', + rest.PowerMaxRest, 'get_initiator_list', return_value=self.data.initiator_list[2]['initiatorId']): with mock.patch.object( - rest.VMAXRest, 'get_initiator_group_from_initiator', + rest.PowerMaxRest, 'get_initiator_group_from_initiator', return_value=None): found_init_group_nam = ( self.driver.masking._find_initiator_group( @@ -7198,7 +7207,7 @@ class VMAXMaskingTest(test.TestCase): self.assertIsNone(found_init_group_nam) def test_create_masking_view(self): - with mock.patch.object(rest.VMAXRest, 'create_masking_view', + with mock.patch.object(rest.PowerMaxRest, 'create_masking_view', side_effect=[None, Exception]): error_message = self.driver.masking.create_masking_view( self.data.array, self.maskingviewdict['maskingview_name'], @@ -7211,12 +7220,12 @@ class VMAXMaskingTest(test.TestCase): self.data.initiatorgroup_name_i, self.extra_specs) self.assertIsNotNone(error_message) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, '_return_volume_to_fast_managed_group') - @mock.patch.object(masking.VMAXMasking, '_check_ig_rollback') + @mock.patch.object(masking.PowerMaxMasking, '_check_ig_rollback') def test_check_if_rollback_action_for_masking_required( self, mock_check_ig, mock_return): - with mock.patch.object(rest.VMAXRest, + with mock.patch.object(rest.PowerMaxRest, 'get_storage_groups_from_volume', side_effect=[ exception.VolumeBackendAPIException, @@ -7228,7 +7237,7 @@ class VMAXMaskingTest(test.TestCase): self.mask.check_if_rollback_action_for_masking_required, self.data.array, self.data.test_volume, self.device_id, self.maskingviewdict) - with mock.patch.object(masking.VMAXMasking, + with mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members'): self.maskingviewdict[ 'default_sg_name'] = self.data.defaultstoragegroup_name @@ -7241,11 +7250,11 @@ class VMAXMaskingTest(test.TestCase): self.device_id, self.data.masking_view_dict_multiattach) mock_return.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'delete_masking_view') - @mock.patch.object(rest.VMAXRest, 'delete_initiator_group') - @mock.patch.object(rest.VMAXRest, 'get_initiator_group') - @mock.patch.object(masking.VMAXMasking, '_find_initiator_group', - return_value=VMAXCommonData.initiatorgroup_name_i) + @mock.patch.object(rest.PowerMaxRest, 'delete_masking_view') + @mock.patch.object(rest.PowerMaxRest, 'delete_initiator_group') + @mock.patch.object(rest.PowerMaxRest, 'get_initiator_group') + @mock.patch.object(masking.PowerMaxMasking, '_find_initiator_group', + return_value=PowerMaxCommonData.initiatorgroup_name_i) def test_verify_initiator_group_from_masking_view( self, mock_find_ig, mock_get_ig, mock_delete_ig, mock_delete_mv): self.mask._verify_initiator_group_from_masking_view( @@ -7262,12 +7271,12 @@ class VMAXMaskingTest(test.TestCase): self.extra_specs) mock_get_ig.assert_called() - @mock.patch.object(rest.VMAXRest, 'delete_masking_view') - @mock.patch.object(rest.VMAXRest, 'delete_initiator_group') - @mock.patch.object(rest.VMAXRest, 'get_initiator_group', + @mock.patch.object(rest.PowerMaxRest, 'delete_masking_view') + @mock.patch.object(rest.PowerMaxRest, 'delete_initiator_group') + @mock.patch.object(rest.PowerMaxRest, 'get_initiator_group', return_value=True) - @mock.patch.object(masking.VMAXMasking, '_find_initiator_group', - return_value=VMAXCommonData.initiatorgroup_name_i) + @mock.patch.object(masking.PowerMaxMasking, '_find_initiator_group', + return_value=PowerMaxCommonData.initiatorgroup_name_i) def test_verify_initiator_group_from_masking_view2( self, mock_find_ig, mock_get_ig, mock_delete_ig, mock_delete_mv): mock_delete_mv.side_effect = [None, Exception] @@ -7286,7 +7295,7 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(self.data.initiatorgroup_name_i, found_ig_from_connector) - @mock.patch.object(rest.VMAXRest, 'create_initiator_group') + @mock.patch.object(rest.PowerMaxRest, 'create_initiator_group') def test_create_initiator_group(self, mock_create_ig): initiator_names = self.mask.find_initiator_names(self.data.connector) ret_init_group_name = self.mask._create_initiator_group( @@ -7294,10 +7303,11 @@ class VMAXMaskingTest(test.TestCase): self.extra_specs) self.assertEqual(self.data.initiatorgroup_name_i, ret_init_group_name) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, '_last_volume_delete_initiator_group') def test_check_ig_rollback(self, mock_last_volume): - with mock.patch.object(masking.VMAXMasking, '_find_initiator_group', + with mock.patch.object(masking.PowerMaxMasking, + '_find_initiator_group', side_effect=[ None, 'FAKE-I-IG', self.data.initiatorgroup_name_i]): @@ -7311,20 +7321,20 @@ class VMAXMaskingTest(test.TestCase): self.data.connector) mock_last_volume.assert_called() - @mock.patch.object(masking.VMAXMasking, '_cleanup_deletion') + @mock.patch.object(masking.PowerMaxMasking, '_cleanup_deletion') def test_remove_and_reset_members(self, mock_cleanup): self.mask.remove_and_reset_members( self.data.array, self.device_id, self.data.test_volume, self.volume_name, self.extra_specs, reset=False) mock_cleanup.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'get_storage_groups_from_volume', - side_effect=[[VMAXCommonData.storagegroup_name_i], - [VMAXCommonData.storagegroup_name_i], - [VMAXCommonData.storagegroup_name_i, - VMAXCommonData.storagegroup_name_f]]) - @mock.patch.object(masking.VMAXMasking, 'remove_volume_from_sg') - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(rest.PowerMaxRest, 'get_storage_groups_from_volume', + side_effect=[[PowerMaxCommonData.storagegroup_name_i], + [PowerMaxCommonData.storagegroup_name_i], + [PowerMaxCommonData.storagegroup_name_i, + PowerMaxCommonData.storagegroup_name_f]]) + @mock.patch.object(masking.PowerMaxMasking, 'remove_volume_from_sg') + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_default_storage_group') def test_cleanup_deletion(self, mock_add, mock_remove_vol, mock_get_sg): self.mask._cleanup_deletion( @@ -7343,14 +7353,14 @@ class VMAXMaskingTest(test.TestCase): self.data.array, self.device_id, self.volume_name, self.extra_specs, volume=self.data.test_volume) - @mock.patch.object(masking.VMAXMasking, '_last_vol_in_sg') - @mock.patch.object(masking.VMAXMasking, '_multiple_vols_in_sg') + @mock.patch.object(masking.PowerMaxMasking, '_last_vol_in_sg') + @mock.patch.object(masking.PowerMaxMasking, '_multiple_vols_in_sg') def test_remove_volume_from_sg(self, mock_multiple_vols, mock_last_vol): with mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', + rest.PowerMaxRest, 'get_masking_views_from_storage_group', return_value=None): with mock.patch.object( - rest.VMAXRest, 'get_num_vols_in_sg', + rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[2, 1]): self.mask.remove_volume_from_sg( self.data.array, self.device_id, self.volume_name, @@ -7361,17 +7371,17 @@ class VMAXMaskingTest(test.TestCase): self.data.defaultstoragegroup_name, self.extra_specs) mock_last_vol.assert_called() - @mock.patch.object(masking.VMAXMasking, '_last_vol_in_sg') - @mock.patch.object(masking.VMAXMasking, '_multiple_vols_in_sg') + @mock.patch.object(masking.PowerMaxMasking, '_last_vol_in_sg') + @mock.patch.object(masking.PowerMaxMasking, '_multiple_vols_in_sg') def test_remove_volume_from_sg_2(self, mock_multiple_vols, mock_last_vol): with mock.patch.object( - rest.VMAXRest, 'is_volume_in_storagegroup', + rest.PowerMaxRest, 'is_volume_in_storagegroup', return_value=True): with mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', + rest.PowerMaxRest, 'get_masking_views_from_storage_group', return_value=[self.data.masking_view_name_i]): with mock.patch.object( - rest.VMAXRest, 'get_num_vols_in_sg', + rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[2, 1]): self.mask.remove_volume_from_sg( self.data.array, self.device_id, self.volume_name, @@ -7382,14 +7392,14 @@ class VMAXMaskingTest(test.TestCase): self.data.storagegroup_name_i, self.extra_specs) mock_last_vol.assert_called() - @mock.patch.object(masking.VMAXMasking, '_last_vol_masking_views', + @mock.patch.object(masking.PowerMaxMasking, '_last_vol_masking_views', return_value=True) - @mock.patch.object(masking.VMAXMasking, '_last_vol_no_masking_views', + @mock.patch.object(masking.PowerMaxMasking, '_last_vol_no_masking_views', return_value=True) def test_last_vol_in_sg(self, mock_no_mv, mock_mv): mv_list = [self.data.masking_view_name_i, self.data.masking_view_name_f] - with mock.patch.object(rest.VMAXRest, + with mock.patch.object(rest.PowerMaxRest, 'get_masking_views_from_storage_group', side_effect=[mv_list, []]): for x in range(0, 2): @@ -7400,12 +7410,14 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(1, mock_mv.call_count) self.assertEqual(1, mock_no_mv.call_count) - @mock.patch.object(masking.VMAXMasking, '_remove_last_vol_and_delete_sg') - @mock.patch.object(masking.VMAXMasking, '_delete_cascaded_storage_groups') - @mock.patch.object(rest.VMAXRest, 'get_num_vols_in_sg', + @mock.patch.object(masking.PowerMaxMasking, + '_remove_last_vol_and_delete_sg') + @mock.patch.object(masking.PowerMaxMasking, + '_delete_cascaded_storage_groups') + @mock.patch.object(rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[1, 3]) - @mock.patch.object(rest.VMAXRest, 'delete_storage_group') - @mock.patch.object(masking.VMAXMasking, 'get_parent_sg_from_child', + @mock.patch.object(rest.PowerMaxRest, 'delete_storage_group') + @mock.patch.object(masking.PowerMaxMasking, 'get_parent_sg_from_child', side_effect=[None, 'parent_sg_name', 'parent_sg_name']) def test_last_vol_no_masking_views( self, mock_get_parent, mock_delete, mock_num_vols, @@ -7419,9 +7431,10 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(1, mock_delete_casc.call_count) self.assertEqual(1, mock_remove.call_count) - @mock.patch.object(masking.VMAXMasking, '_remove_last_vol_and_delete_sg') - @mock.patch.object(masking.VMAXMasking, '_delete_mv_ig_and_sg') - @mock.patch.object(masking.VMAXMasking, '_get_num_vols_from_mv', + @mock.patch.object(masking.PowerMaxMasking, + '_remove_last_vol_and_delete_sg') + @mock.patch.object(masking.PowerMaxMasking, '_delete_mv_ig_and_sg') + @mock.patch.object(masking.PowerMaxMasking, '_get_num_vols_from_mv', side_effect=[(1, 'parent_name'), (3, 'parent_name')]) def test_last_vol_masking_views( self, mock_num_vols, mock_delete_all, mock_remove): @@ -7434,10 +7447,11 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(1, mock_delete_all.call_count) self.assertEqual(1, mock_remove.call_count) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_default_storage_group') - @mock.patch.object(rest.VMAXRest, 'get_num_vols_in_sg') - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') + @mock.patch.object(rest.PowerMaxRest, 'get_num_vols_in_sg') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') def test_multiple_vols_in_sg(self, mock_remove_vol, mock_get_volumes, mock_add): self.mask._multiple_vols_in_sg( @@ -7449,11 +7463,13 @@ class VMAXMaskingTest(test.TestCase): self.volume_name, self.extra_specs, True) mock_add.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'get_element_from_masking_view') - @mock.patch.object(masking.VMAXMasking, '_last_volume_delete_masking_view') - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(rest.PowerMaxRest, 'get_element_from_masking_view') + @mock.patch.object(masking.PowerMaxMasking, + '_last_volume_delete_masking_view') + @mock.patch.object(masking.PowerMaxMasking, '_last_volume_delete_initiator_group') - @mock.patch.object(masking.VMAXMasking, '_delete_cascaded_storage_groups') + @mock.patch.object(masking.PowerMaxMasking, + '_delete_cascaded_storage_groups') def test_delete_mv_ig_and_sg(self, mock_delete_sg, mock_delete_ig, mock_delete_mv, mock_get_element): self.mask._delete_mv_ig_and_sg( @@ -7463,17 +7479,18 @@ class VMAXMaskingTest(test.TestCase): self.data.connector, True, self.data.extra_specs) mock_delete_sg.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'delete_masking_view') + @mock.patch.object(rest.PowerMaxRest, 'delete_masking_view') def test_last_volume_delete_masking_view(self, mock_delete_mv): self.mask._last_volume_delete_masking_view( self.data.array, self.data.masking_view_name_i) mock_delete_mv.assert_called_once() - @mock.patch.object(masking.VMAXMasking, 'return_volume_to_volume_group') - @mock.patch.object(rest.VMAXRest, 'move_volume_between_storage_groups') - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, + 'return_volume_to_volume_group') + @mock.patch.object(rest.PowerMaxRest, 'move_volume_between_storage_groups') + @mock.patch.object(masking.PowerMaxMasking, 'get_or_create_default_storage_group') - @mock.patch.object(masking.VMAXMasking, 'add_volume_to_storage_group') + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_storage_group') def test_add_volume_to_default_storage_group( self, mock_add_sg, mock_get_sg, mock_move, mock_return): self.mask.add_volume_to_default_storage_group( @@ -7492,7 +7509,7 @@ class VMAXMaskingTest(test.TestCase): mock_return.assert_called_once() def test_add_volume_to_default_storage_group_next_gen(self): - with mock.patch.object(rest.VMAXRest, 'is_next_gen_array', + with mock.patch.object(rest.PowerMaxRest, 'is_next_gen_array', return_value=True): with mock.patch.object( self.mask, 'get_or_create_default_storage_group'): @@ -7505,20 +7522,20 @@ class VMAXMaskingTest(test.TestCase): 'NONE', self.extra_specs, False, False, None)) - @mock.patch.object(provision.VMAXProvision, 'create_storage_group') + @mock.patch.object(provision.PowerMaxProvision, 'create_storage_group') def test_get_or_create_default_storage_group(self, mock_create_sg): with mock.patch.object( - rest.VMAXRest, 'get_vmax_default_storage_group', + rest.PowerMaxRest, 'get_vmax_default_storage_group', return_value=(None, self.data.storagegroup_name_i)): storage_group_name = self.mask.get_or_create_default_storage_group( self.data.array, self.data.srp, self.data.slo, self.data.workload, self.extra_specs) self.assertEqual(self.data.storagegroup_name_i, storage_group_name) with mock.patch.object( - rest.VMAXRest, 'get_vmax_default_storage_group', + rest.PowerMaxRest, 'get_vmax_default_storage_group', return_value=("test_sg", self.data.storagegroup_name_i)): with mock.patch.object( - rest.VMAXRest, 'get_masking_views_from_storage_group', + rest.PowerMaxRest, 'get_masking_views_from_storage_group', return_value=self.data.masking_view_name_i): self.assertRaises( exception.VolumeBackendAPIException, @@ -7526,11 +7543,12 @@ class VMAXMaskingTest(test.TestCase): self.data.array, self.data.srp, self.data.slo, self.data.workload, self.extra_specs) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_default_storage_group') - @mock.patch.object(rest.VMAXRest, 'remove_child_sg_from_parent_sg') - @mock.patch.object(rest.VMAXRest, 'delete_storage_group') - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') + @mock.patch.object(rest.PowerMaxRest, 'remove_child_sg_from_parent_sg') + @mock.patch.object(rest.PowerMaxRest, 'delete_storage_group') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') def test_remove_last_vol_and_delete_sg(self, mock_vol_sg, mock_delete_sg, mock_rm, mock_add): self.mask._remove_last_vol_and_delete_sg( @@ -7545,7 +7563,7 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(1, mock_rm.call_count) self.assertEqual(1, mock_add.call_count) - @mock.patch.object(rest.VMAXRest, 'delete_initiator_group') + @mock.patch.object(rest.PowerMaxRest, 'delete_initiator_group') def test_last_volume_delete_initiator_group(self, mock_delete_ig): self.mask._last_volume_delete_initiator_group( self.data.array, self.data.initiatorgroup_name_f, 'Wrong_Host') @@ -7555,7 +7573,7 @@ class VMAXMaskingTest(test.TestCase): mock_delete_ig.assert_not_called() mv_list = [self.data.masking_view_name_i, self.data.masking_view_name_f] - with mock.patch.object(rest.VMAXRest, + with mock.patch.object(rest.PowerMaxRest, 'get_masking_views_by_initiator_group', side_effect=[mv_list, []]): self.mask._last_volume_delete_initiator_group( @@ -7589,8 +7607,8 @@ class VMAXMaskingTest(test.TestCase): mv_dict = deepcopy(self.data.masking_view_dict) mv_dict['initiator_check'] = True with mock.patch.object( - rest.VMAXRest, 'get_element_from_masking_view', - return_value=VMAXCommonData.initiatorgroup_name_f): + rest.PowerMaxRest, 'get_element_from_masking_view', + return_value=PowerMaxCommonData.initiatorgroup_name_f): with mock.patch.object( self.mask, '_verify_initiator_group_from_masking_view', return_value=(True, self.data.initiatorgroup_name_f)): @@ -7605,10 +7623,10 @@ class VMAXMaskingTest(test.TestCase): self.data.storagegroup_name_f, self.data.port_group_name_f, self.data.extra_specs)) - @mock.patch.object(masking.VMAXMasking, 'add_child_sg_to_parent_sg', + @mock.patch.object(masking.PowerMaxMasking, 'add_child_sg_to_parent_sg', side_effect=[ None, exception.VolumeBackendAPIException]) - @mock.patch.object(rest.VMAXRest, 'is_child_sg_in_parent_sg', + @mock.patch.object(rest.PowerMaxRest, 'is_child_sg_in_parent_sg', side_effect=[True, False, False]) def test_check_add_child_sg_to_parent_sg(self, mock_is_child, mock_add): for x in range(0, 3): @@ -7617,8 +7635,8 @@ class VMAXMaskingTest(test.TestCase): self.data.parent_sg_i, self.data.extra_specs) self.assertIsNotNone(message) - @mock.patch.object(rest.VMAXRest, 'add_child_sg_to_parent_sg') - @mock.patch.object(rest.VMAXRest, 'is_child_sg_in_parent_sg', + @mock.patch.object(rest.PowerMaxRest, 'add_child_sg_to_parent_sg') + @mock.patch.object(rest.PowerMaxRest, 'is_child_sg_in_parent_sg', side_effect=[True, False]) def test_add_child_sg_to_parent_sg(self, mock_is_child, mock_add): for x in range(0, 2): @@ -7637,18 +7655,18 @@ class VMAXMaskingTest(test.TestCase): self.data.array, self.data.storagegroup_name_f) self.assertEqual(self.data.parent_sg_f, sg_name2) - @mock.patch.object(rest.VMAXRest, 'get_element_from_masking_view', + @mock.patch.object(rest.PowerMaxRest, 'get_element_from_masking_view', return_value='parent_sg') - @mock.patch.object(rest.VMAXRest, 'get_num_vols_in_sg', + @mock.patch.object(rest.PowerMaxRest, 'get_num_vols_in_sg', return_value=2) def test_get_num_vols_from_mv(self, mock_num, mock_element): num_vols, sg = self.mask._get_num_vols_from_mv( self.data.array, self.data.masking_view_name_f) self.assertEqual(2, num_vols) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_default_storage_group') - @mock.patch.object(rest.VMAXRest, 'delete_storage_group') + @mock.patch.object(rest.PowerMaxRest, 'delete_storage_group') def test_delete_cascaded(self, mock_delete, mock_add): self.mask._delete_cascaded_storage_groups( self.data.array, self.data.masking_view_name_f, @@ -7665,7 +7683,7 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(1, mock_delete.call_count) mock_add.assert_called_once() - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'add_volumes_to_storage_group') def test_add_remote_vols_to_volume_group(self, mock_add): self.mask.add_remote_vols_to_volume_group( @@ -7673,8 +7691,9 @@ class VMAXMaskingTest(test.TestCase): self.data.rep_extra_specs) mock_add.assert_called_once() - @mock.patch.object(masking.VMAXMasking, 'add_remote_vols_to_volume_group') - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, + 'add_remote_vols_to_volume_group') + @mock.patch.object(masking.PowerMaxMasking, '_check_adding_volume_to_storage_group') @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=True) @@ -7691,7 +7710,7 @@ class VMAXMaskingTest(test.TestCase): self.data.test_volume.name, self.data.extra_specs) mock_add.assert_called_once() - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, '_return_volume_to_fast_managed_group') def test_pre_multiattach(self, mock_return): mv_dict = self.mask.pre_multiattach( @@ -7711,18 +7730,18 @@ class VMAXMaskingTest(test.TestCase): mock_return.assert_called_once() def test_pre_multiattach_next_gen(self): - with mock.patch.object(utils.VMAXUtils, 'truncate_string', + with mock.patch.object(utils.PowerMaxUtils, 'truncate_string', return_value='DiamondDSS'): self.mask.pre_multiattach( self.data.array, self.data.device_id, self.data.masking_view_dict_multiattach, self.data.extra_specs) - utils.VMAXUtils.truncate_string.assert_called_once_with( + utils.PowerMaxUtils.truncate_string.assert_called_once_with( 'DiamondDSS', 10) - @mock.patch.object(rest.VMAXRest, 'get_storage_group_list', + @mock.patch.object(rest.PowerMaxRest, 'get_storage_group_list', side_effect=[{'storageGroupId': [ - VMAXCommonData.no_slo_sg_name]}, {}]) - @mock.patch.object(masking.VMAXMasking, + PowerMaxCommonData.no_slo_sg_name]}, {}]) + @mock.patch.object(masking.PowerMaxMasking, '_return_volume_to_fast_managed_group') def test_check_return_volume_to_fast_managed_group( self, mock_return, mock_sg): @@ -7735,13 +7754,14 @@ class VMAXMaskingTest(test.TestCase): self.data.array, self.data.device_id, no_slo_specs) mock_return.assert_called_once() - @mock.patch.object(masking.VMAXMasking, '_move_vol_from_default_sg') - @mock.patch.object(masking.VMAXMasking, '_clean_up_child_storage_group') - @mock.patch.object(masking.VMAXMasking, 'add_child_sg_to_parent_sg') - @mock.patch.object(masking.VMAXMasking, '_get_or_create_storage_group') - @mock.patch.object(rest.VMAXRest, 'get_storage_groups_from_volume', - side_effect=[[VMAXCommonData.no_slo_sg_name], - [VMAXCommonData.storagegroup_name_f]]) + @mock.patch.object(masking.PowerMaxMasking, '_move_vol_from_default_sg') + @mock.patch.object(masking.PowerMaxMasking, + '_clean_up_child_storage_group') + @mock.patch.object(masking.PowerMaxMasking, 'add_child_sg_to_parent_sg') + @mock.patch.object(masking.PowerMaxMasking, '_get_or_create_storage_group') + @mock.patch.object(rest.PowerMaxRest, 'get_storage_groups_from_volume', + side_effect=[[PowerMaxCommonData.no_slo_sg_name], + [PowerMaxCommonData.storagegroup_name_f]]) def test_return_volume_to_fast_managed_group( self, mock_sg, mock_get, mock_add, mock_clean, mock_move): for x in range(0, 2): @@ -7752,13 +7772,13 @@ class VMAXMaskingTest(test.TestCase): mock_get.assert_called_once() mock_clean.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'delete_storage_group') - @mock.patch.object(rest.VMAXRest, 'remove_child_sg_from_parent_sg') - @mock.patch.object(rest.VMAXRest, 'is_child_sg_in_parent_sg', + @mock.patch.object(rest.PowerMaxRest, 'delete_storage_group') + @mock.patch.object(rest.PowerMaxRest, 'remove_child_sg_from_parent_sg') + @mock.patch.object(rest.PowerMaxRest, 'is_child_sg_in_parent_sg', side_effect=[False, True]) - @mock.patch.object(rest.VMAXRest, 'get_num_vols_in_sg', + @mock.patch.object(rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[2, 0, 0]) - @mock.patch.object(rest.VMAXRest, 'get_storage_group', side_effect=[ + @mock.patch.object(rest.PowerMaxRest, 'get_storage_group', side_effect=[ None, 'child_sg', 'child_sg', 'child_sg']) def test_clean_up_child_storage_group( self, mock_sg, mock_num, mock_child, mock_rm, mock_del): @@ -7785,11 +7805,11 @@ class VMAXMaskingTest(test.TestCase): self.assertEqual(2, mock_del.call_count) -class VMAXCommonReplicationTest(test.TestCase): +class PowerMaxCommonReplicationTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXCommonReplicationTest, self).setUp() + super(PowerMaxCommonReplicationTest, self).setUp() self.replication_device = { 'target_device_id': self.data.remote_array, 'remote_port_group': self.data.port_group_name_f, @@ -7804,16 +7824,16 @@ class VMAXCommonReplicationTest(test.TestCase): san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_f], replication_device=self.replication_device) - rest.VMAXRest._establish_rest_session = mock.Mock( + rest.PowerMaxRest._establish_rest_session = mock.Mock( return_value=FakeRequestsSession()) - driver = fc.VMAXFCDriver(configuration=configuration) + driver = fc.PowerMaxFCDriver(configuration=configuration) iscsi_config = FakeConfiguration( None, 'CommonReplicationTests', 1, 1, san_ip='1.1.1.1', san_login='smc', vmax_array=self.data.array, vmax_srp='SRP_1', san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_i], replication_device=self.replication_device) - iscsi_driver = iscsi.VMAXISCSIDriver(configuration=iscsi_config) + iscsi_driver = iscsi.PowerMaxISCSIDriver(configuration=iscsi_config) self.iscsi_common = iscsi_driver.common self.driver = driver self.common = self.driver.common @@ -7840,7 +7860,8 @@ class VMAXCommonReplicationTest(test.TestCase): san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_f], replication_device=self.async_rep_device) - self.async_driver = fc.VMAXFCDriver(configuration=async_configuration) + self.async_driver = fc.PowerMaxFCDriver( + configuration=async_configuration) self.metro_rep_device = { 'target_device_id': self.data.remote_array, 'remote_port_group': self.data.port_group_name_f, @@ -7853,7 +7874,8 @@ class VMAXCommonReplicationTest(test.TestCase): san_password='smc', san_api_port=8443, vmax_port_groups=[self.data.port_group_name_f], replication_device=self.metro_rep_device) - self.metro_driver = fc.VMAXFCDriver(configuration=metro_configuration) + self.metro_driver = fc.PowerMaxFCDriver( + configuration=metro_configuration) def test_get_replication_info(self): self.common._get_replication_info() @@ -7862,16 +7884,16 @@ class VMAXCommonReplicationTest(test.TestCase): @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=False) @mock.patch.object(objects.Group, 'get_by_id', - return_value=VMAXCommonData.test_rep_group) + return_value=PowerMaxCommonData.test_rep_group) @mock.patch.object(volume_utils, 'is_group_a_type', return_value=True) - @mock.patch.object(utils.VMAXUtils, 'check_replication_matched', + @mock.patch.object(utils.PowerMaxUtils, 'check_replication_matched', return_value=True) - @mock.patch.object(masking.VMAXMasking, 'add_volume_to_storage_group') + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_storage_group') @mock.patch.object( - common.VMAXCommon, '_replicate_volume', + common.PowerMaxCommon, '_replicate_volume', return_value=({ 'replication_driver_data': - VMAXCommonData.test_volume.replication_driver_data}, {})) + PowerMaxCommonData.test_volume.replication_driver_data}, {})) def test_create_replicated_volume(self, mock_rep, mock_add, mock_match, mock_check, mock_get, mock_cg): extra_specs = deepcopy(self.extra_specs) @@ -7940,11 +7962,11 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.array, self.data.test_volume, "1", volume_dict, self.extra_specs) - @mock.patch.object(common.VMAXCommon, '_remove_members') - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_remove_members') + @mock.patch.object(common.PowerMaxCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.rep_extra_specs) - @mock.patch.object(utils.VMAXUtils, 'is_volume_failed_over', + return_value=PowerMaxCommonData.rep_extra_specs) + @mock.patch.object(utils.PowerMaxUtils, 'is_volume_failed_over', return_value=True) def test_unmap_lun_volume_failed_over(self, mock_fo, mock_es, mock_rm): extra_specs = deepcopy(self.extra_specs) @@ -7954,23 +7976,24 @@ class VMAXCommonReplicationTest(test.TestCase): self.common._unmap_lun(self.data.test_volume, self.data.connector) mock_es.assert_called_once_with(extra_specs, rep_config) - @mock.patch.object(common.VMAXCommon, '_remove_members') - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_remove_members') + @mock.patch.object(common.PowerMaxCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.rep_extra_specs) - @mock.patch.object(utils.VMAXUtils, 'is_metro_device', return_value=True) + return_value=PowerMaxCommonData.rep_extra_specs) + @mock.patch.object(utils.PowerMaxUtils, 'is_metro_device', + return_value=True) def test_unmap_lun_metro(self, mock_md, mock_es, mock_rm): extra_specs = deepcopy(self.extra_specs) extra_specs[utils.PORTGROUPNAME] = self.data.port_group_name_f self.common._unmap_lun(self.data.test_volume, self.data.connector) self.assertEqual(2, mock_rm.call_count) - @mock.patch.object(utils.VMAXUtils, 'is_volume_failed_over', + @mock.patch.object(utils.PowerMaxUtils, 'is_volume_failed_over', return_value=True) def test_initialize_connection_vol_failed_over(self, mock_fo): extra_specs = deepcopy(self.extra_specs) extra_specs[utils.PORTGROUPNAME] = self.data.port_group_name_f - rep_extra_specs = deepcopy(VMAXCommonData.rep_extra_specs) + rep_extra_specs = deepcopy(PowerMaxCommonData.rep_extra_specs) rep_extra_specs[utils.PORTGROUPNAME] = self.data.port_group_name_f rep_config = self.utils.get_replication_config( [self.replication_device]) @@ -7980,7 +8003,8 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.test_volume, self.data.connector) mock_es.assert_called_once_with(extra_specs, rep_config) - @mock.patch.object(utils.VMAXUtils, 'is_metro_device', return_value=True) + @mock.patch.object(utils.PowerMaxUtils, 'is_metro_device', + return_value=True) def test_initialize_connection_vol_metro(self, mock_md): metro_connector = deepcopy(self.data.connector) metro_connector['multipath'] = True @@ -7993,12 +8017,13 @@ class VMAXCommonReplicationTest(test.TestCase): 'metro_hostlunid': 3} self.assertEqual(ref_dict, info_dict) - @mock.patch.object(rest.VMAXRest, 'get_iscsi_ip_address_and_iqn', - return_value=([VMAXCommonData.ip], - VMAXCommonData.initiator)) - @mock.patch.object(common.VMAXCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.rep_extra_specs) - @mock.patch.object(utils.VMAXUtils, 'is_metro_device', return_value=True) + @mock.patch.object(rest.PowerMaxRest, 'get_iscsi_ip_address_and_iqn', + return_value=([PowerMaxCommonData.ip], + PowerMaxCommonData.initiator)) + @mock.patch.object(common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=PowerMaxCommonData.rep_extra_specs) + @mock.patch.object(utils.PowerMaxUtils, 'is_metro_device', + return_value=True) def test_initialize_connection_vol_metro_iscsi(self, mock_md, mock_es, mock_ip): metro_connector = deepcopy(self.data.connector) @@ -8017,17 +8042,18 @@ class VMAXCommonReplicationTest(test.TestCase): 'iqn': self.data.initiator}]} self.assertEqual(ref_dict, info_dict) - @mock.patch.object(utils.VMAXUtils, 'is_metro_device', return_value=True) + @mock.patch.object(utils.PowerMaxUtils, 'is_metro_device', + return_value=True) def test_initialize_connection_no_multipath_iscsi(self, mock_md): info_dict = self.iscsi_common.initialize_connection( self.data.test_volume, self.data.connector) self.assertIsNone(info_dict) @mock.patch.object( - masking.VMAXMasking, 'pre_multiattach', - return_value=VMAXCommonData.masking_view_dict_multiattach) + masking.PowerMaxMasking, 'pre_multiattach', + return_value=PowerMaxCommonData.masking_view_dict_multiattach) def test_attach_metro_volume(self, mock_pre): - rep_extra_specs = deepcopy(VMAXCommonData.rep_extra_specs) + rep_extra_specs = deepcopy(PowerMaxCommonData.rep_extra_specs) rep_extra_specs[utils.PORTGROUPNAME] = self.data.port_group_name_f hostlunid, remote_port_group = self.common._attach_metro_volume( self.data.test_volume, self.data.connector, False, @@ -8039,10 +8065,10 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.extra_specs, rep_extra_specs) mock_pre.assert_called_once() - @mock.patch.object(rest.VMAXRest, 'is_vol_in_rep_session', + @mock.patch.object(rest.PowerMaxRest, 'is_vol_in_rep_session', return_value=(False, False, None)) - @mock.patch.object(common.VMAXCommon, 'extend_volume_is_replicated') - @mock.patch.object(common.VMAXCommon, '_sync_check') + @mock.patch.object(common.PowerMaxCommon, 'extend_volume_is_replicated') + @mock.patch.object(common.PowerMaxCommon, '_sync_check') def test_extend_volume_rep_enabled(self, mock_sync, mock_ex_re, mock_is_re): extra_specs = deepcopy(self.extra_specs) @@ -8067,7 +8093,7 @@ class VMAXCommonReplicationTest(test.TestCase): self.assertEqual('OS-HostX-SRP_1-DiamondDSS-OS-fibre-PG-RE', masking_dict[utils.SG_NAME]) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_replicate_volume', return_value=({}, {})) def test_manage_existing_is_replicated(self, mock_rep): @@ -8086,7 +8112,7 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.test_volume, volume_name, provider_location, extra_specs, delete_src=False) - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_setup_volume_replication(self, mock_rm): rep_status, rep_data, __ = self.common.setup_volume_replication( self.data.array, self.data.test_volume, self.data.device_id, @@ -8095,8 +8121,8 @@ class VMAXCommonReplicationTest(test.TestCase): self.assertEqual({'array': self.data.remote_array, 'device_id': self.data.device_id}, rep_data) - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') - @mock.patch.object(common.VMAXCommon, '_create_volume') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') + @mock.patch.object(common.PowerMaxCommon, '_create_volume') def test_setup_volume_replication_target(self, mock_create, mock_rm): rep_status, rep_data, __ = self.common.setup_volume_replication( self.data.array, self.data.test_volume, self.data.device_id, @@ -8106,7 +8132,7 @@ class VMAXCommonReplicationTest(test.TestCase): 'device_id': self.data.device_id2}, rep_data) mock_create.assert_not_called() - @mock.patch.object(common.VMAXCommon, '_cleanup_remote_target') + @mock.patch.object(common.PowerMaxCommon, '_cleanup_remote_target') def test_cleanup_lun_replication_success(self, mock_clean): rep_extra_specs = deepcopy(self.data.rep_extra_specs) rep_extra_specs[utils.PORTGROUPNAME] = self.data.port_group_name_f @@ -8128,7 +8154,7 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.device_id2, self.data.rdf_group_no, "1", rep_extra_specs) - @mock.patch.object(common.VMAXCommon, '_cleanup_remote_target') + @mock.patch.object(common.PowerMaxCommon, '_cleanup_remote_target') def test_cleanup_lun_replication_no_target(self, mock_clean): with mock.patch.object(self.common, 'get_remote_target_device', return_value=(None, '', '', '', '')): @@ -8138,9 +8164,9 @@ class VMAXCommonReplicationTest(test.TestCase): mock_clean.assert_not_called() @mock.patch.object( - common.VMAXCommon, 'get_remote_target_device', - return_value=(VMAXCommonData.device_id2, '', '', '', '')) - @mock.patch.object(common.VMAXCommon, + common.PowerMaxCommon, 'get_remote_target_device', + return_value=(PowerMaxCommonData.device_id2, '', '', '', '')) + @mock.patch.object(common.PowerMaxCommon, '_add_volume_to_async_rdf_managed_grp') def test_cleanup_lun_replication_exception(self, mock_add, mock_tgt): self.assertRaises(exception.VolumeBackendAPIException, @@ -8156,10 +8182,11 @@ class VMAXCommonReplicationTest(test.TestCase): extra_specs) mock_add.assert_called_once() - @mock.patch.object(common.VMAXCommon, '_cleanup_metro_target') - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') - @mock.patch.object(common.VMAXCommon, '_delete_from_srp') - @mock.patch.object(provision.VMAXProvision, 'break_rdf_relationship') + @mock.patch.object(common.PowerMaxCommon, '_cleanup_metro_target') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') + @mock.patch.object(common.PowerMaxCommon, '_delete_from_srp') + @mock.patch.object(provision.PowerMaxProvision, 'break_rdf_relationship') def test_cleanup_remote_target(self, mock_break, mock_del, mock_rm, mock_clean_metro): with mock.patch.object(self.rest, 'are_vols_rdf_paired', @@ -8199,8 +8226,8 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.device_id, self.data.device_id2, self.data.rdf_group_name, "vol1", extra_specs) - @mock.patch.object(provision.VMAXProvision, 'enable_group_replication') - @mock.patch.object(rest.VMAXRest, 'get_num_vols_in_sg', + @mock.patch.object(provision.PowerMaxProvision, 'enable_group_replication') + @mock.patch.object(rest.PowerMaxRest, 'get_num_vols_in_sg', side_effect=[2, 0]) def test_cleanup_metro_target(self, mock_vols, mock_enable): # allow delete is True @@ -8218,10 +8245,11 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.device_id2, self.data.rdf_group_no, specs) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_remove_vol_and_cleanup_replication') - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') - @mock.patch.object(common.VMAXCommon, '_delete_from_srp') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') + @mock.patch.object(common.PowerMaxCommon, '_delete_from_srp') def test_cleanup_replication_source(self, mock_del, mock_rm, mock_clean): self.common._cleanup_replication_source( self.data.array, self.data.test_volume, "vol1", @@ -8248,7 +8276,7 @@ class VMAXCommonReplicationTest(test.TestCase): self.common.failover_host(volumes) mock_fo.assert_called_once() - @mock.patch.object(common.VMAXCommon, 'failover_replication', + @mock.patch.object(common.PowerMaxCommon, 'failover_replication', return_value=({}, {})) def test_failover_host_groups(self, mock_fg): volumes = [self.data.test_volume_group_member] @@ -8281,10 +8309,10 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.device_id)) self.assertIsNone(target_device4) - @mock.patch.object(common.VMAXCommon, 'setup_volume_replication') - @mock.patch.object(provision.VMAXProvision, 'extend_volume') - @mock.patch.object(provision.VMAXProvision, 'break_rdf_relationship') - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(common.PowerMaxCommon, 'setup_volume_replication') + @mock.patch.object(provision.PowerMaxProvision, 'extend_volume') + @mock.patch.object(provision.PowerMaxProvision, 'break_rdf_relationship') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_extend_volume_is_replicated(self, mock_remove, mock_break, mock_extend, mock_setup): self.common.extend_volume_is_replicated( @@ -8316,8 +8344,9 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.device_id, 'vol1', '1', self.data.extra_specs_rep_enabled) - @mock.patch.object(common.VMAXCommon, 'add_volume_to_replication_group') - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(common.PowerMaxCommon, + 'add_volume_to_replication_group') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_enable_rdf(self, mock_remove, mock_add): rep_config = self.utils.get_replication_config( [self.replication_device]) @@ -8328,8 +8357,9 @@ class VMAXCommonReplicationTest(test.TestCase): self.assertEqual(2, mock_remove.call_count) self.assertEqual(2, mock_add.call_count) - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') - @mock.patch.object(common.VMAXCommon, '_cleanup_remote_target') + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') + @mock.patch.object(common.PowerMaxCommon, '_cleanup_remote_target') def test_enable_rdf_exception(self, mock_cleanup, mock_rm): rep_config = self.utils.get_replication_config( [self.replication_device]) @@ -8346,7 +8376,7 @@ class VMAXCommonReplicationTest(test.TestCase): self.extra_specs) self.assertEqual(self.data.default_sg_re_enabled, sg_name) - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'get_or_create_default_storage_group', side_effect=exception.VolumeBackendAPIException) def test_add_volume_to_replication_group_exception(self, mock_get): @@ -8509,28 +8539,29 @@ class VMAXCommonReplicationTest(test.TestCase): self.assertEqual(fields.ReplicationStatus.ERROR, model_update['replication_status']) - @mock.patch.object(provision.VMAXProvision, 'failover_group') + @mock.patch.object(provision.PowerMaxProvision, 'failover_group') def test_failover_replication_metro(self, mock_fo): volumes = [self.data.test_volume] _, vol_model_updates = self.common._failover_replication( volumes, group, None, host=True, is_metro=True) mock_fo.assert_not_called() - @mock.patch.object(utils.VMAXUtils, 'get_volume_group_utils', - return_value=(VMAXCommonData.array, {})) - @mock.patch.object(common.VMAXCommon, '_cleanup_group_replication') + @mock.patch.object(utils.PowerMaxUtils, 'get_volume_group_utils', + return_value=(PowerMaxCommonData.array, {})) + @mock.patch.object(common.PowerMaxCommon, '_cleanup_group_replication') @mock.patch.object(volume_utils, 'is_group_a_type', return_value=True) def test_delete_replication_group(self, mock_check, mock_cleanup, mock_utils): self.common._delete_group(self.data.test_rep_group, []) mock_cleanup.assert_called_once() - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'remove_volumes_from_storage_group') - @mock.patch.object(utils.VMAXUtils, 'check_rep_status_enabled') - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(utils.PowerMaxUtils, 'check_rep_status_enabled') + @mock.patch.object(common.PowerMaxCommon, '_remove_remote_vols_from_volume_group') - @mock.patch.object(masking.VMAXMasking, 'add_remote_vols_to_volume_group') + @mock.patch.object(masking.PowerMaxMasking, + 'add_remote_vols_to_volume_group') @mock.patch.object(volume_utils, 'is_group_a_type', return_value=True) @mock.patch.object(volume_utils, 'is_group_a_cg_snapshot_type', return_value=True) @@ -8544,7 +8575,7 @@ class VMAXCommonReplicationTest(test.TestCase): mock_add.assert_called_once() mock_remove.assert_called_once() - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'remove_volumes_from_storage_group') def test_remove_remote_vols_from_volume_group(self, mock_rm): self.common._remove_remote_vols_from_volume_group( @@ -8552,8 +8583,8 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.test_rep_group, self.data.rep_extra_specs) mock_rm.assert_called_once() - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') - @mock.patch.object(masking.VMAXMasking, + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_volumes_from_storage_group') def test_cleanup_group_replication(self, mock_rm, mock_rm_reset): self.common._cleanup_group_replication( @@ -8561,7 +8592,7 @@ class VMAXCommonReplicationTest(test.TestCase): [self.data.device_id], self.extra_specs) mock_rm.assert_called_once() - @mock.patch.object(masking.VMAXMasking, 'add_volume_to_storage_group') + @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_storage_group') def test_add_volume_to_async_group(self, mock_add): extra_specs = deepcopy(self.extra_specs) extra_specs['rep_mode'] = utils.REP_ASYNC @@ -8579,9 +8610,9 @@ class VMAXCommonReplicationTest(test.TestCase): self.data.failed_resource, self.data.device_id, 'name', self.data.remote_array, self.data.device_id2, extra_specs) - @mock.patch.object(common.VMAXCommon, + @mock.patch.object(common.PowerMaxCommon, '_add_volume_to_async_rdf_managed_grp') - @mock.patch.object(masking.VMAXMasking, 'remove_and_reset_members') + @mock.patch.object(masking.PowerMaxMasking, 'remove_and_reset_members') def test_setup_volume_replication_async(self, mock_rm, mock_add): extra_specs = deepcopy(self.extra_specs) extra_specs['rep_mode'] = utils.REP_ASYNC @@ -8594,27 +8625,29 @@ class VMAXCommonReplicationTest(test.TestCase): 'device_id': self.data.device_id}, rep_data) mock_add.assert_called_once() - @mock.patch.object(common.VMAXCommon, '_failover_replication', + @mock.patch.object(common.PowerMaxCommon, '_failover_replication', return_value=({}, {})) def test_failover_host_async(self, mock_fg): volumes = [self.data.test_volume] extra_specs = deepcopy(self.extra_specs) extra_specs['rep_mode'] = utils.REP_ASYNC - with mock.patch.object(common.VMAXCommon, '_initial_setup', + with mock.patch.object(common.PowerMaxCommon, '_initial_setup', return_value=extra_specs): self.async_driver.common.failover_host(volumes, None, []) mock_fg.assert_called_once() - @mock.patch.object(common.VMAXCommon, '_retype_volume', return_value=True) - @mock.patch.object(masking.VMAXMasking, 'remove_vol_from_storage_group') - @mock.patch.object(common.VMAXCommon, '_retype_remote_volume', + @mock.patch.object(common.PowerMaxCommon, '_retype_volume', return_value=True) - @mock.patch.object(common.VMAXCommon, 'setup_volume_replication', + @mock.patch.object(masking.PowerMaxMasking, + 'remove_vol_from_storage_group') + @mock.patch.object(common.PowerMaxCommon, '_retype_remote_volume', + return_value=True) + @mock.patch.object(common.PowerMaxCommon, 'setup_volume_replication', return_value=( - '', VMAXCommonData.provider_location2, '')) - @mock.patch.object(common.VMAXCommon, + '', PowerMaxCommonData.provider_location2, '')) + @mock.patch.object(common.PowerMaxCommon, '_remove_vol_and_cleanup_replication') - @mock.patch.object(utils.VMAXUtils, 'is_replication_enabled', + @mock.patch.object(utils.PowerMaxUtils, 'is_replication_enabled', side_effect=[False, True, True, False, True, True]) def test_migrate_volume_replication(self, mock_re, mock_rm_rep, mock_setup, mock_retype, @@ -8631,13 +8664,15 @@ class VMAXCommonReplicationTest(test.TestCase): mock_retype.assert_called_once() @mock.patch.object( - common.VMAXCommon, '_get_replication_extra_specs', - return_value=VMAXCommonData.extra_specs_rep_enabled) + common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=PowerMaxCommonData.extra_specs_rep_enabled) @mock.patch.object( - rest.VMAXRest, 'get_storage_groups_from_volume', + rest.PowerMaxRest, 'get_storage_groups_from_volume', side_effect=[ - VMAXCommonData.storagegroup_list, ['OS-SRP_1-Diamond-DSS-RE-SG']]) - @mock.patch.object(common.VMAXCommon, '_retype_volume', return_value=True) + PowerMaxCommonData.storagegroup_list, + ['OS-SRP_1-Diamond-DSS-RE-SG']]) + @mock.patch.object(common.PowerMaxCommon, '_retype_volume', + return_value=True) def test_retype_volume_replication(self, mock_retype, mock_sg, mock_es): for x in range(0, 2): self.common._retype_remote_volume( @@ -8647,16 +8682,17 @@ class VMAXCommonReplicationTest(test.TestCase): mock_retype.assert_called_once() -class VMAXVolumeMetadataNoDebugTest(test.TestCase): +class PowerMaxVolumeMetadataNoDebugTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXVolumeMetadataNoDebugTest, self).setUp() + super(PowerMaxVolumeMetadataNoDebugTest, self).setUp() is_debug = False - self.volume_metadata = metadata.VMAXVolumeMetadata( - rest.VMAXRest, '3.1', is_debug) + self.volume_metadata = metadata.PowerMaxVolumeMetadata( + rest.PowerMaxRest, '3.1', is_debug) - @mock.patch.object(metadata.VMAXVolumeMetadata, '_fill_volume_trace_dict', + @mock.patch.object(metadata.PowerMaxVolumeMetadata, + '_fill_volume_trace_dict', return_value={}) def test_gather_volume_info(self, mock_fvtd): self.volume_metadata.gather_volume_info( @@ -8664,25 +8700,26 @@ class VMAXVolumeMetadataNoDebugTest(test.TestCase): mock_fvtd.assert_not_called() -class VMAXVolumeMetadataDebugTest(test.TestCase): +class PowerMaxVolumeMetadataDebugTest(test.TestCase): def setUp(self): - self.data = VMAXCommonData() + self.data = PowerMaxCommonData() - super(VMAXVolumeMetadataDebugTest, self).setUp() + super(PowerMaxVolumeMetadataDebugTest, self).setUp() is_debug = True - self.volume_metadata = metadata.VMAXVolumeMetadata( - rest.VMAXRest, '3.1', is_debug) + self.volume_metadata = metadata.PowerMaxVolumeMetadata( + rest.PowerMaxRest, '3.1', is_debug) self.utils = self.volume_metadata.utils self.rest = self.volume_metadata.rest - @mock.patch.object(metadata.VMAXVolumeMetadata, '_fill_volume_trace_dict', + @mock.patch.object(metadata.PowerMaxVolumeMetadata, + '_fill_volume_trace_dict', return_value={}) def test_gather_volume_info(self, mock_fvtd): self.volume_metadata.gather_volume_info( self.data.volume_id, 'create', False, volume_size=1) mock_fvtd.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_attach_info(self, mock_uvim): @@ -8692,7 +8729,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): False, False) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_create_volume(self, mock_uvim): @@ -8701,14 +8738,14 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): "test_group_id", self.data.extra_specs, {}, 'create', None) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_delete_info(self, mock_uvim): self.volume_metadata.capture_delete_info(self.data.test_volume) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_manage_existing(self, mock_uvim): @@ -8717,7 +8754,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): self.data.extra_specs) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_failover_volume(self, mock_uvim): @@ -8729,7 +8766,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): fields.ReplicationStatus.FAILED_OVER, utils.REP_SYNC) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_modify_group(self, mock_uvim): @@ -8738,7 +8775,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): [], self.data.array) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_extend_info(self, mock_uvim): @@ -8747,7 +8784,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): self.data.extra_specs, self.data.array) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_detach_info(self, mock_uvim): @@ -8756,7 +8793,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): None, None) mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_snapshot_info(self, mock_uvim): @@ -8765,7 +8802,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): 'ss-test-vol') mock_uvim.assert_called_once() - @mock.patch.object(metadata.VMAXVolumeMetadata, + @mock.patch.object(metadata.PowerMaxVolumeMetadata, 'update_volume_info_metadata', return_value={}) def test_capture_retype_info(self, mock_uvim): @@ -8817,7 +8854,7 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): sg_list=sg_list) self.assertEqual(result_dict, volume_metadata) - @mock.patch.object(utils.VMAXUtils, 'merge_dicts', + @mock.patch.object(utils.PowerMaxUtils, 'merge_dicts', return_value={}) def test_consolidate_volume_trace_list(self, mock_m2d): self.volume_metadata.volume_trace_list = [self.data.data_dict] @@ -8860,20 +8897,20 @@ class VMAXVolumeMetadataDebugTest(test.TestCase): self.assertEqual('OS-fibre-PG', result_dict['port_group']) @mock.patch.object(platform, 'platform', - return_value=VMAXCommonData.platform) + return_value=PowerMaxCommonData.platform) @mock.patch.object(platform, 'python_version', - return_value=VMAXCommonData.python_version) + return_value=PowerMaxCommonData.python_version) @mock.patch.object(openstack_version.version_info, 'version_string', - return_value=VMAXCommonData.openstack_version) + return_value=PowerMaxCommonData.openstack_version) @mock.patch.object(openstack_version.version_info, 'release_string', - return_value=VMAXCommonData.openstack_release) - @mock.patch.object(rest.VMAXRest, 'get_unisphere_version', + return_value=PowerMaxCommonData.openstack_release) + @mock.patch.object(rest.PowerMaxRest, 'get_unisphere_version', return_value={ - 'version': VMAXCommonData.unisphere_version}) - @mock.patch.object(rest.VMAXRest, 'get_array_serial', + 'version': PowerMaxCommonData.unisphere_version}) + @mock.patch.object(rest.PowerMaxRest, 'get_array_serial', return_value={ - 'ucode': VMAXCommonData.vmax_firmware_version, - 'model': VMAXCommonData.vmax_model}) + 'ucode': PowerMaxCommonData.vmax_firmware_version, + 'model': PowerMaxCommonData.vmax_model}) def test_gather_version_info( self, mock_vi, mock_ur, mock_or, mock_ov, mock_pv, mock_p): self.volume_metadata.gather_version_info(self.data.array) diff --git a/cinder/volume/drivers/dell_emc/vmax/__init__.py b/cinder/volume/drivers/dell_emc/powermax/__init__.py similarity index 100% rename from cinder/volume/drivers/dell_emc/vmax/__init__.py rename to cinder/volume/drivers/dell_emc/powermax/__init__.py diff --git a/cinder/volume/drivers/dell_emc/vmax/common.py b/cinder/volume/drivers/dell_emc/powermax/common.py similarity index 96% rename from cinder/volume/drivers/dell_emc/vmax/common.py rename to cinder/volume/drivers/dell_emc/powermax/common.py index b52651fd581..5ffc27291e8 100644 --- a/cinder/volume/drivers/dell_emc/vmax/common.py +++ b/cinder/volume/drivers/dell_emc/powermax/common.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -31,11 +31,11 @@ from cinder import exception from cinder.i18n import _ from cinder.objects import fields from cinder.volume import configuration -from cinder.volume.drivers.dell_emc.vmax import masking -from cinder.volume.drivers.dell_emc.vmax import metadata as volume_metadata -from cinder.volume.drivers.dell_emc.vmax import provision -from cinder.volume.drivers.dell_emc.vmax import rest -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import masking +from cinder.volume.drivers.dell_emc.powermax import metadata as volume_metadata +from cinder.volume.drivers.dell_emc.powermax import provision +from cinder.volume.drivers.dell_emc.powermax import rest +from cinder.volume.drivers.dell_emc.powermax import utils from cinder.volume import utils as volume_utils from cinder.volume import volume_types LOG = logging.getLogger(__name__) @@ -53,7 +53,7 @@ FAILOVER_ERROR = fields.ReplicationStatus.FAILOVER_ERROR REPLICATION_ERROR = fields.ReplicationStatus.ERROR -vmax_opts = [ +powermax_opts = [ cfg.IntOpt('interval', default=3, help='Use this value to specify ' @@ -64,10 +64,9 @@ vmax_opts = [ 'number of retries.'), cfg.IntOpt(utils.VMAX_SNAPVX_UNLINK_LIMIT, default=3, - help='Use this value to specify ' - 'the maximum number of unlinks ' - 'for the temporary snapshots ' - 'before a clone operation.'), + help='DEPRECATED: vmax_snapvc_unlink_limit.', + deprecated_for_removal=True, + deprecated_reason='Replaced by powermax_snapvx_unlink_limit.'), cfg.BoolOpt('initiator_check', default=False, help='Use this value to enable ' @@ -81,21 +80,25 @@ vmax_opts = [ default=8443, help='REST server port number.'), cfg.StrOpt(utils.VMAX_ARRAY, - help='Serial number of the array to connect to.'), + help='DEPRECATED: vmax_array.', + deprecated_for_removal=True, + deprecated_reason='Replaced by powermax_array.'), cfg.StrOpt(utils.VMAX_SRP, - help='Storage resource pool on array to use for ' - 'provisioning.'), + help='DEPRECATED: vmax_srp.', + deprecated_for_removal=True, + deprecated_reason='Replaced by powermax_srp.'), cfg.StrOpt(utils.VMAX_SERVICE_LEVEL, - help='Service level to use for provisioning storage. ' - 'Setting this as an extra spec in pool_name ' - 'is preferable.'), + help='DEPRECATED: vmax_service_level.', + deprecated_for_removal=True, + deprecated_reason='Replaced by powermax_service_level.'), cfg.StrOpt(utils.VMAX_WORKLOAD, help='Workload, setting this as an extra spec in ' 'pool_name is preferable.'), cfg.ListOpt(utils.VMAX_PORT_GROUPS, bounds=True, - help='List of port groups containing frontend ports ' - 'configured prior for server connection.'), + help='DEPRECATED: vmax_port_groups.', + deprecated_for_removal=True, + deprecated_reason='Replaced by powermax_port_groups.'), cfg.IntOpt(utils.U4P_FAILOVER_TIMEOUT, default=20.0, help='How long to wait for the server to send data before ' @@ -120,17 +123,37 @@ vmax_opts = [ 'connection is re-established.'), cfg.MultiOpt(utils.U4P_FAILOVER_TARGETS, item_type=types.Dict(), - help='Dictionary of Unisphere failover target info.')] - -CONF.register_opts(vmax_opts, group=configuration.SHARED_CONF_GROUP) + help='Dictionary of Unisphere failover target info.'), + cfg.IntOpt(utils.POWERMAX_SNAPVX_UNLINK_LIMIT, + default=3, + help='Use this value to specify ' + 'the maximum number of unlinks ' + 'for the temporary snapshots ' + 'before a clone operation.'), + cfg.StrOpt(utils.POWERMAX_ARRAY, + help='Serial number of the array to connect to.'), + cfg.StrOpt(utils.POWERMAX_SRP, + help='Storage resource pool on array to use for ' + 'provisioning.'), + cfg.StrOpt(utils.POWERMAX_SERVICE_LEVEL, + help='Service level to use for provisioning storage. ' + 'Setting this as an extra spec in pool_name ' + 'is preferable.'), + cfg.ListOpt(utils.POWERMAX_PORT_GROUPS, + bounds=True, + help='List of port groups containing frontend ports ' + 'configured prior for server connection.')] -class VMAXCommon(object): - """Common class for Rest based VMAX volume drivers. +CONF.register_opts(powermax_opts, group=configuration.SHARED_CONF_GROUP) - This common class is for Dell EMC VMAX volume drivers + +class PowerMaxCommon(object): + """Common class for Rest based PowerMax volume drivers. + + This common class is for Dell EMC PowerMax volume drivers based on UniSphere Rest API. - It supports VMAX 3 and VMAX All Flash arrays. + It supports VMAX 3 and VMAX All Flash and PowerMax arrays. """ pool_info = {'backend_name': None, @@ -145,13 +168,13 @@ class VMAXCommon(object): self.protocol = prtcl self.configuration = configuration - self.configuration.append_config_values(vmax_opts) - self.rest = rest.VMAXRest() - self.utils = utils.VMAXUtils() - self.masking = masking.VMAXMasking(prtcl, self.rest) - self.provision = provision.VMAXProvision(self.rest) + self.configuration.append_config_values(powermax_opts) + self.rest = rest.PowerMaxRest() + self.utils = utils.PowerMaxUtils() + self.masking = masking.PowerMaxMasking(prtcl, self.rest) + self.provision = provision.PowerMaxProvision(self.rest) self.version = version - self.volume_metadata = volume_metadata.VMAXVolumeMetadata( + self.volume_metadata = volume_metadata.PowerMaxVolumeMetadata( self.rest, version, LOG.isEnabledFor(logging.DEBUG)) # replication self.replication_enabled = False @@ -186,8 +209,9 @@ class VMAXCommon(object): """Get relevent details from configuration file.""" self.interval = self.configuration.safe_get('interval') self.retries = self.configuration.safe_get('retries') - self.snapvx_unlink_limit = self.configuration.safe_get( - utils.VMAX_SNAPVX_UNLINK_LIMIT) + self.snapvx_unlink_limit = self._get_unlink_configuration_value( + utils.VMAX_SNAPVX_UNLINK_LIMIT, + utils.POWERMAX_SNAPVX_UNLINK_LIMIT) self.pool_info['backend_name'] = ( self.configuration.safe_get('volume_backend_name')) mosr = volume_utils.get_max_over_subscription_ratio( @@ -247,13 +271,13 @@ class VMAXCommon(object): LOG.warning("There has been no failover instances of Unisphere " "configured for this instance of Cinder. If your " "primary instance of Unisphere goes down then your " - "VMAX will be inaccessible until the Unisphere REST " - "API is responsive again.") + "PowerMax/VMAX will be inaccessible until the " + "Unisphere REST API is responsive again.") def retest_primary_u4p(self): """Retest connection to the primary instance of Unisphere.""" primary_array_info = self.get_attributes_from_cinder_config() - temp_conn = rest.VMAXRest() + temp_conn = rest.PowerMaxRest() temp_conn.set_rest_credentials(primary_array_info) LOG.debug( "Running connection check to primary instance of Unisphere " @@ -310,8 +334,8 @@ class VMAXCommon(object): {'rep_config': self.rep_config}) elif self.rep_devices and len(self.rep_devices) > 1: LOG.error("More than one replication target is configured. " - "Dell EMC VMAX only suppports a single replication " - "target. Replication will not be enabled.") + "Dell EMC PowerMax/VMAX only suppports a single " + "replication target. Replication will not be enabled.") def _get_slo_workload_combinations(self, array_info): """Method to query the array for SLO and Workloads. @@ -383,7 +407,7 @@ class VMAXCommon(object): return finalarrayinfolist def create_volume(self, volume): - """Creates a EMC(VMAX) volume from a storage group. + """Creates a EMC(PowerMax/VMAX) volume from a storage group. :param volume: volume object :returns: model_update - dict @@ -548,7 +572,7 @@ class VMAXCommon(object): replication_driver_data)}, rep_info_dict) def delete_volume(self, volume): - """Deletes a EMC(VMAX) volume. + """Deletes a EMC(PowerMax/VMAX) volume. :param volume: volume object """ @@ -617,7 +641,7 @@ class VMAXCommon(object): Removes volume from the storage group that belongs to a masking view. :param array: the array serial number :param volume: volume object - :param device_id: the VMAX volume device id + :param device_id: the PowerMax/VMAX volume device id :param extra_specs: extra specifications :param connector: the connector object :param is_multiattach: flag to indicate if this is a multiattach case @@ -839,9 +863,9 @@ class VMAXCommon(object): extra_specs, rep_extra_specs): """Helper method to attach a metro volume. - Metro protected volumes point to two VMAX devices on different arrays, - which are presented as a single device to the host. This method - masks the remote device to the host. + Metro protected volumes point to two PowerMax/VMAX devices on + different arrays, which are presented as a single device to the host. + This method masks the remote device to the host. :param volume: the volume object :param connector: the connector dict :param is_multiattach: flag to indicate if this a multiattach case @@ -941,8 +965,8 @@ class VMAXCommon(object): exception_message = ( _("The volume: %(volume)s is a snapshot source. " "Extending a volume with snapVx snapshots is only " - "supported on VMAX from HyperMaxOS version 5978 " - "onwards. Exiting...") % {'volume': volume_name}) + "supported on PowerMax/VMAX from HyperMaxOS version " + "5978 onwards. Exiting...") % {'volume': volume_name}) LOG.error(exception_message) raise exception.VolumeBackendAPIException( message=exception_message) @@ -1020,7 +1044,7 @@ class VMAXCommon(object): 'array': array_info['SerialNumber']}) if already_queried: - # The dictionary will only have one key per VMAX + # The dictionary will only have one key per PowerMax/VMAX # Construct the location info try: temp_location_info = ( @@ -1181,7 +1205,7 @@ class VMAXCommon(object): return extra_specs, qos_specs def _find_device_on_array(self, volume, extra_specs): - """Given the volume get the VMAX device Id. + """Given the volume get the PowerMax/VMAX device Id. :param volume: volume object :param extra_specs: the extra Specs @@ -1663,7 +1687,7 @@ class VMAXCommon(object): return volume_dict def _set_vmax_extra_specs(self, extra_specs, pool_record): - """Set the VMAX extra specs. + """Set the PowerMax/PowerMax/VMAX extra specs. The pool_name extra spec must be set, otherwise a default slo/workload will be chosen. The portgroup can either be passed as an extra spec @@ -1944,7 +1968,7 @@ class VMAXCommon(object): clone_id = clone_volume.id clone_name = self.utils.get_volume_element_name(clone_id) create_snap = False - # VMAX supports using a target volume that is bigger than + # PowerMax/VMAX supports using a target volume that is bigger than # the source volume, so we create the target volume the desired # size at this point to avoid having to extend later try: @@ -2105,7 +2129,7 @@ class VMAXCommon(object): do_delete_temp_volume_snap(source) def manage_existing(self, volume, external_ref): - """Manages an existing VMAX Volume (import to Cinder). + """Manages an existing PowerMax/VMAX Volume (import to Cinder). Renames the existing volume to match the expected name for the volume. Also need to consider things like QoS, Emulation, account/tenant. @@ -2176,7 +2200,7 @@ class VMAXCommon(object): :param device_id: the device id :param volume_id: the cinder volume id :param external_ref: the external reference - :returns volume_identifier - name of the volume on VMAX + :returns volume_identifier - name of the volume on PowerMax/VMAX :returns sg - the storage group which the LUN belongs to :raises: ManageExistingInvalidReference, ManageExistingAlreadyManaged: """ @@ -2229,7 +2253,7 @@ class VMAXCommon(object): return volume_identifier, sg def manage_existing_get_size(self, volume, external_ref): - """Return size of an existing VMAX volume to manage_existing. + """Return size of an existing PowerMax/VMAX volume to manage_existing. :param self: reference to class :param volume: the volume object including the volume_type_id @@ -2251,7 +2275,7 @@ class VMAXCommon(object): size = float(self.rest.get_size_of_device_on_array(array, device_id)) if not size.is_integer(): exception_message = ( - _("Cannot manage existing VMAX volume %(device_id)s " + _("Cannot manage existing PowerMax/VMAX volume %(device_id)s " "- it has a size of %(vol_size)s but only whole GB " "sizes are supported. Please extend the " "volume to the nearest GB value before importing.") @@ -2265,7 +2289,7 @@ class VMAXCommon(object): return int(size) def unmanage(self, volume): - """Export VMAX volume from Cinder. + """Export PowerMax/VMAX volume from Cinder. Leave the volume intact on the backend array. @@ -2313,7 +2337,7 @@ class VMAXCommon(object): volume_id, extra_specs) def manage_existing_snapshot(self, snapshot, existing_ref): - """Manage an existing VMAX Snapshot (import to Cinder). + """Manage an existing PowerMax/VMAX Snapshot (import to Cinder). Renames the Snapshot to prefix it with OS- to indicate it is managed by Cinder @@ -2409,7 +2433,7 @@ class VMAXCommon(object): extra_specs[utils.ARRAY], device_id) def unmanage_snapshot(self, snapshot): - """Export VMAX Snapshot from Cinder. + """Export PowerMax/VMAX Snapshot from Cinder. Leaves the snapshot intact on the backend VMAX @@ -2425,7 +2449,7 @@ class VMAXCommon(object): exception_message = ( _("It is not possible to unmanage a snapshot where the " "source volume is failed-over, revert back to source " - "VMAX to unmanage snapshot %(snap_name)s") + "PowerMax/VMAX to unmanage snapshot %(snap_name)s") % {'snap_name': snap_name}) LOG.exception(exception_message) @@ -2452,7 +2476,7 @@ class VMAXCommon(object): self._sync_check(array, device_id, volume.name, extra_specs) LOG.info("Snapshot %(snap_name)s is no longer managed in " - "OpenStack but still remains on VMAX source " + "OpenStack but still remains on PowerMax/VMAX source " "%(array_id)s", {'snap_name': snap_name, 'array_id': array}) def get_manageable_volumes(self, marker, limit, offset, sort_keys, @@ -2477,11 +2501,11 @@ class VMAXCommon(object): 'array_id': array}) volumes = self.rest.get_private_volume_list(array) - # No volumes returned from VMAX + # No volumes returned from PowerMax/VMAX if not volumes: - LOG.info("There were no volumes found on the backend VMAX. " - "You need to create some volumes before they can be " - "managed into Cinder.") + LOG.info("There were no volumes found on the backend " + "PowerMax/VMAX. You need to create some volumes before " + "they can be managed into Cinder.") return manageable_vols for device in volumes: @@ -2561,11 +2585,11 @@ class VMAXCommon(object): 'array_id': array}) volumes = self.rest.get_private_volume_list(array) - # No volumes returned from VMAX + # No volumes returned from PowerMax/VMAX if not volumes: - LOG.info("There were no volumes found on the backend VMAX. " - "You need to create some volumes before snapshots can " - "be created and managed into Cinder.") + LOG.info("There were no volumes found on the backend " + "PowerMax/VMAX. You need to create some volumes " + "before snashot can be created and managed into Cinder.") return manageable_snaps for device in volumes: @@ -2638,7 +2662,8 @@ class VMAXCommon(object): manageable_snaps = manageable_snaps[snap_index:] else: msg = (_("Snapshot marker %(marker)s not found, marker " - "provided must be a valid VMAX snapshot ID") % + "provided must be a valid PowerMax/VMAX " + "snapshot ID") % {'marker': marker}) raise exception.VolumeBackendAPIException(msg) @@ -3625,7 +3650,7 @@ class VMAXCommon(object): self, array, device_id, volume_name, extra_specs): """Add a volume to the default replication group. - Replication groups are VMAX storage groups that contain only + Replication groups are PowerMax/VMAX storage groups that contain only RDF-paired volumes. We can use our normal storage group operations. :param array: array serial number :param device_id: the device id @@ -4264,8 +4289,8 @@ class VMAXCommon(object): LOG.error(error_msg) raise exception.VolumeBackendAPIException(message=error_msg) - LOG.debug("Enter VMAX create_volume group_from_src. Group to be " - "created: %(grpId)s, Source : %(SourceGrpId)s.", + LOG.debug("Enter PowerMax/VMAX create_volume group_from_src. Group " + "to be created: %(grpId)s, Source : %(SourceGrpId)s.", {'grpId': group.id, 'SourceGrpId': source_id}) try: @@ -4632,19 +4657,22 @@ class VMAXCommon(object): username = self.configuration.safe_get(utils.VMAX_USER_NAME) password = self.configuration.safe_get(utils.VMAX_PASSWORD) if username and password: - serial_number = self.configuration.safe_get(utils.VMAX_ARRAY) + serial_number = self._get_configuration_value( + utils.VMAX_ARRAY, utils.POWERMAX_ARRAY) if serial_number is None: LOG.error("Array Serial Number must be set in cinder.conf") - srp_name = self.configuration.safe_get(utils.VMAX_SRP) + srp_name = self._get_configuration_value( + utils.VMAX_SRP, utils.POWERMAX_SRP) if srp_name is None: LOG.error("SRP Name must be set in cinder.conf") - slo = self.configuration.safe_get(utils.VMAX_SERVICE_LEVEL) + slo = self._get_configuration_value( + utils.VMAX_SERVICE_LEVEL, utils.POWERMAX_SERVICE_LEVEL) workload = self.configuration.safe_get(utils.VMAX_WORKLOAD) - port_groups = self.configuration.safe_get(utils.VMAX_PORT_GROUPS) + port_groups = self._get_configuration_value( + utils.VMAX_PORT_GROUPS, utils.POWERMAX_PORT_GROUPS) random_portgroup = None if port_groups: - random_portgroup = random.choice(self.configuration.safe_get( - utils.VMAX_PORT_GROUPS)) + random_portgroup = random.choice(port_groups) kwargs = ( {'RestServerIp': self.configuration.safe_get( @@ -4670,6 +4698,41 @@ class VMAXCommon(object): return kwargs + def _get_configuration_value(self, first_key, second_key): + """Get the configuration value of the first or second key + + :param first_key: the first key + :param second_key: the second key + :returns: value + """ + return_value = None + if (self.configuration.safe_get(first_key) + and self.configuration.safe_get(second_key)): + LOG.error("Cannot specifiy both %(first_key)s. " + "and %(second_key)s.", + {'first_key': first_key, 'second_key': second_key}) + else: + return_value = self.configuration.safe_get(first_key) + if return_value is None: + return_value = self.configuration.safe_get(second_key) + return return_value + + def _get_unlink_configuration_value(self, first_key, second_key): + """Get the configuration value of snapvx_unlink_limit + + This will give back the value of the default snapvx_unlink_limit + unless either powermax_snapvx_unlink_limit or vmax_snapvx_unlink_limit + is set to something else + + :param first_key: the first key + :param second_key: the second key + :returns: value + """ + return_value = self.configuration.safe_get(second_key) + if return_value == 3: + return_value = self.configuration.safe_get(first_key) + return return_value + def _get_unisphere_port(self): """Get unisphere port from the configuration file @@ -4680,7 +4743,7 @@ class VMAXCommon(object): elif self.configuration.safe_get(utils.VMAX_SERVER_PORT_NEW): return self.configuration.safe_get(utils.VMAX_SERVER_PORT_NEW) else: - LOG.debug("VMAX port is not set, using default port: %s", + LOG.debug("PowerMax/VMAX port is not set, using default port: %s", utils.DEFAULT_PORT) return utils.DEFAULT_PORT diff --git a/cinder/volume/drivers/dell_emc/vmax/fc.py b/cinder/volume/drivers/dell_emc/powermax/fc.py similarity index 95% rename from cinder/volume/drivers/dell_emc/vmax/fc.py rename to cinder/volume/drivers/dell_emc/powermax/fc.py index ac971fb5e51..76f791e1ed0 100644 --- a/cinder/volume/drivers/dell_emc/vmax/fc.py +++ b/cinder/volume/drivers/dell_emc/powermax/fc.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -19,7 +19,7 @@ from oslo_log import log as logging from cinder import interface from cinder.volume import driver -from cinder.volume.drivers.dell_emc.vmax import common +from cinder.volume.drivers.dell_emc.powermax import common from cinder.volume.drivers.san import san from cinder.zonemanager import utils as fczm_utils @@ -27,8 +27,8 @@ LOG = logging.getLogger(__name__) @interface.volumedriver -class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): - """FC Drivers for VMAX using REST. +class PowerMaxFCDriver(san.SanDriver, driver.FibreChannelDriver): + """FC Drivers for PowerMax using REST. Version history: @@ -98,23 +98,24 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): - Fix for SSL verification/cert application (bug #1772924) - Log VMAX metadata of a volume (bp vmax-metadata) - Fix for get-pools command (bug #1784856) - 3.3.0 - Fix for initiator retrieval and short hostname unmapping + 4.0.0 - Fix for initiator retrieval and short hostname unmapping (bugs #1783855 #1783867) - Fix for HyperMax OS Upgrade Bug (bug #1790141) - Support for failover to secondary Unisphere (bp/vmax-unisphere-failover) + - Rebrand from VMAX to PowerMax(bp/vmax-powermax-rebrand) """ - VERSION = "3.3.0" + VERSION = "4.0.0" # ThirdPartySystems wiki CI_WIKI_NAME = "EMC_VMAX_CI" def __init__(self, *args, **kwargs): - super(VMAXFCDriver, self).__init__(*args, **kwargs) + super(PowerMaxFCDriver, self).__init__(*args, **kwargs) self.active_backend_id = kwargs.get('active_backend_id', None) - self.common = common.VMAXCommon( + self.common = common.PowerMaxCommon( 'FC', self.VERSION, configuration=self.configuration, @@ -125,7 +126,7 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): pass def create_volume(self, volume): - """Creates a VMAX volume. + """Creates a PowerMax/VMAX volume. :param volume: the cinder volume object :returns: provider location dict @@ -152,7 +153,7 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): return self.common.create_cloned_volume(volume, src_vref) def delete_volume(self, volume): - """Deletes a VMAX volume. + """Deletes a PowerMax/VMAX volume. :param volume: the cinder volume object """ @@ -474,18 +475,18 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): self._stats = data def manage_existing(self, volume, external_ref): - """Manages an existing VMAX Volume (import to Cinder). + """Manages an existing PowerMax/VMAX Volume (import to Cinder). Renames the Volume to match the expected name for the volume. Also need to consider things like QoS, Emulation, account/tenant. :param volume: the volume object - :param external_ref: the reference for the VMAX volume + :param external_ref: the reference for the PowerMax/VMAX volume :returns: model_update """ return self.common.manage_existing(volume, external_ref) def manage_existing_get_size(self, volume, external_ref): - """Return size of an existing VMAX volume to manage_existing. + """Return size of an existing PowerMax/VMAX volume to manage_existing. :param self: reference to class :param volume: the volume object including the volume_type_id @@ -495,20 +496,20 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): return self.common.manage_existing_get_size(volume, external_ref) def unmanage(self, volume): - """Export VMAX volume from Cinder. + """Export PowerMax/VMAX volume from Cinder. Leave the volume intact on the backend array. """ return self.common.unmanage(volume) def manage_existing_snapshot(self, snapshot, existing_ref): - """Manage an existing VMAX Snapshot (import to Cinder). + """Manage an existing PowerMax/VMAX Snapshot (import to Cinder). Renames the Snapshot to prefix it with OS- to indicate it is managed by Cinder. :param snapshot: the snapshot object - :param existing_ref: the snapshot name on the backend VMAX + :param existing_ref: the snapshot name on the backend PowerMax/VMAX :returns: model_update """ return self.common.manage_existing_snapshot(snapshot, existing_ref) @@ -517,15 +518,15 @@ class VMAXFCDriver(san.SanDriver, driver.FibreChannelDriver): """Return the size of the source volume for manage-existing-snapshot. :param snapshot: the snapshot object - :param existing_ref: the snapshot name on the backend VMAX + :param existing_ref: the snapshot name on the backend PowerMax/VMAX :returns: size of the source volume in GB """ return self.common.manage_existing_snapshot_get_size(snapshot) def unmanage_snapshot(self, snapshot): - """Export VMAX Snapshot from Cinder. + """Export PowerMax/VMAX Snapshot from Cinder. - Leaves the snapshot intact on the backend VMAX. + Leaves the snapshot intact on the backend PowerMax/VMAX. :param snapshot: the snapshot object """ diff --git a/cinder/volume/drivers/dell_emc/vmax/iscsi.py b/cinder/volume/drivers/dell_emc/powermax/iscsi.py similarity index 95% rename from cinder/volume/drivers/dell_emc/vmax/iscsi.py rename to cinder/volume/drivers/dell_emc/powermax/iscsi.py index c3f218cb0a9..24b85e565c8 100644 --- a/cinder/volume/drivers/dell_emc/vmax/iscsi.py +++ b/cinder/volume/drivers/dell_emc/powermax/iscsi.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. """ -ISCSI Drivers for Dell EMC VMAX arrays based on REST. +ISCSI Drivers for Dell EMC PowerMax/PowerMax/VMAX arrays based on REST. """ from oslo_log import log as logging @@ -23,15 +23,15 @@ import six from cinder import exception from cinder.i18n import _ from cinder import interface -from cinder.volume.drivers.dell_emc.vmax import common +from cinder.volume.drivers.dell_emc.powermax import common from cinder.volume.drivers.san import san LOG = logging.getLogger(__name__) @interface.volumedriver -class VMAXISCSIDriver(san.SanISCSIDriver): - """ISCSI Drivers for VMAX using Rest. +class PowerMaxISCSIDriver(san.SanISCSIDriver): + """ISCSI Drivers for PowerMax using Rest. Version history: @@ -103,24 +103,25 @@ class VMAXISCSIDriver(san.SanISCSIDriver): - Fix for SSL verification/cert application (bug #1772924) - Log VMAX metadata of a volume (bp vmax-metadata) - Fix for get-pools command (bug #1784856) - 3.3.0 - Fix for initiator retrieval and short hostname unmapping + 4.0.0 - Fix for initiator retrieval and short hostname unmapping (bugs #1783855 #1783867) - Fix for HyperMax OS Upgrade Bug (bug #1790141) - Support for failover to secondary Unisphere (bp/vmax-unisphere-failover) + - Rebrand from VMAX to PowerMax(bp/vmax-powermax-rebrand) """ - VERSION = "3.3.0" + VERSION = "4.0.0" # ThirdPartySystems wiki CI_WIKI_NAME = "EMC_VMAX_CI" def __init__(self, *args, **kwargs): - super(VMAXISCSIDriver, self).__init__(*args, **kwargs) + super(PowerMaxISCSIDriver, self).__init__(*args, **kwargs) self.active_backend_id = kwargs.get('active_backend_id', None) self.common = ( - common.VMAXCommon( + common.PowerMaxCommon( 'iSCSI', self.VERSION, configuration=self.configuration, @@ -130,7 +131,7 @@ class VMAXISCSIDriver(san.SanISCSIDriver): pass def create_volume(self, volume): - """Creates a VMAX volume. + """Creates a PowerMax/VMAX volume. :param volume: the cinder volume object :returns: provider location dict @@ -157,7 +158,7 @@ class VMAXISCSIDriver(san.SanISCSIDriver): return self.common.create_cloned_volume(volume, src_vref) def delete_volume(self, volume): - """Deletes a VMAX volume. + """Deletes a PowerMax/VMAX volume. :param volume: the cinder volume object """ @@ -397,7 +398,7 @@ class VMAXISCSIDriver(san.SanISCSIDriver): self._stats = data def manage_existing(self, volume, external_ref): - """Manages an existing VMAX Volume (import to Cinder). + """Manages an existing PowerMax/VMAX Volume (import to Cinder). Renames the Volume to match the expected name for the volume. Also need to consider things like QoS, Emulation, account/tenant. @@ -405,7 +406,7 @@ class VMAXISCSIDriver(san.SanISCSIDriver): return self.common.manage_existing(volume, external_ref) def manage_existing_get_size(self, volume, external_ref): - """Return size of an existing VMAX volume to manage_existing. + """Return size of an existing PowerMax/VMAX volume to manage_existing. :param self: reference to class :param volume: the volume object including the volume_type_id @@ -415,20 +416,20 @@ class VMAXISCSIDriver(san.SanISCSIDriver): return self.common.manage_existing_get_size(volume, external_ref) def unmanage(self, volume): - """Export VMAX volume from Cinder. + """Export PowerMax/VMAX volume from Cinder. Leave the volume intact on the backend array. """ return self.common.unmanage(volume) def manage_existing_snapshot(self, snapshot, existing_ref): - """Manage an existing VMAX Snapshot (import to Cinder). + """Manage an existing PowerMax/VMAX Snapshot (import to Cinder). Renames the Snapshot to prefix it with OS- to indicate it is managed by Cinder. :param snapshot: the snapshot object - :param existing_ref: the snapshot name on the backend VMAX + :param existing_ref: the snapshot name on the backend PowerMax/VMAX :returns: model_update """ return self.common.manage_existing_snapshot(snapshot, existing_ref) @@ -437,15 +438,15 @@ class VMAXISCSIDriver(san.SanISCSIDriver): """Return the size of the source volume for manage-existing-snapshot. :param snapshot: the snapshot object - :param existing_ref: the snapshot name on the backend VMAX + :param existing_ref: the snapshot name on the backend PowerMax/VMAX :returns: size of the source volume in GB """ return self.common.manage_existing_snapshot_get_size(snapshot) def unmanage_snapshot(self, snapshot): - """Export VMAX Snapshot from Cinder. + """Export PowerMax/VMAX Snapshot from Cinder. - Leaves the snapshot intact on the backend VMAX. + Leaves the snapshot intact on the backend PowerMax/VMAX. :param snapshot: the snapshot object """ diff --git a/cinder/volume/drivers/dell_emc/vmax/masking.py b/cinder/volume/drivers/dell_emc/powermax/masking.py similarity index 99% rename from cinder/volume/drivers/dell_emc/vmax/masking.py rename to cinder/volume/drivers/dell_emc/powermax/masking.py index c4ed61c1a6a..9dca1605b08 100644 --- a/cinder/volume/drivers/dell_emc/vmax/masking.py +++ b/cinder/volume/drivers/dell_emc/powermax/masking.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -24,24 +24,24 @@ import six from cinder import coordination from cinder import exception from cinder.i18n import _ -from cinder.volume.drivers.dell_emc.vmax import provision -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import provision +from cinder.volume.drivers.dell_emc.powermax import utils from cinder.volume import utils as volume_utils LOG = logging.getLogger(__name__) -class VMAXMasking(object): - """Masking class for Dell EMC VMAX. +class PowerMaxMasking(object): + """Masking class for Dell EMC PowerMax. Masking code to dynamically create a masking view. - It supports VMAX arrays. + It supports VMAX 3, All Flash and PowerMax arrays. """ def __init__(self, prtcl, rest): self.protocol = prtcl - self.utils = utils.VMAXUtils() + self.utils = utils.PowerMaxUtils() self.rest = rest - self.provision = provision.VMAXProvision(self.rest) + self.provision = provision.PowerMaxProvision(self.rest) def setup_masking_view( self, serial_number, volume, masking_view_dict, extra_specs): @@ -877,8 +877,8 @@ class VMAXMasking(object): contains the correct initiators. If it does not contain the correct initiators then we delete the initiator group from the masking view, re-create it with the correct initiators and add it to the masking view - NOTE: VMAX does not support ModifyMaskingView so we must first - delete the masking view and recreate it. + NOTE: PowerMax/VMAX does not support ModifyMaskingView so we must + first delete the masking view and recreate it. :param serial_number: the array serial number :param maskingview_name: name of the masking view :param maskingview_dict: the masking view dict @@ -1551,8 +1551,8 @@ class VMAXMasking(object): self, serial_number, initiatorgroup_name, host): """Delete the initiator group. - Delete the Initiator group if it has been created by the VMAX driver, - and if there are no masking views associated with it. + Delete the Initiator group if it has been created by the PowerMax + driver, and if there are no masking views associated with it. :param serial_number: the array serial number :param initiatorgroup_name: initiator group name :param host: the short name of the host @@ -1591,8 +1591,8 @@ class VMAXMasking(object): 'nmv': len(maskingview_names)}) else: LOG.warning("Initiator group %(ig_name)s was " - "not created by the VMAX driver so will " - "not be deleted by the VMAX driver.", + "not created by the PowerMax driver so will " + "not be deleted by the PowerMax driver.", {'ig_name': initiatorgroup_name}) else: LOG.warning("Cannot get host name from connector object - " diff --git a/cinder/volume/drivers/dell_emc/vmax/metadata.py b/cinder/volume/drivers/dell_emc/powermax/metadata.py similarity index 97% rename from cinder/volume/drivers/dell_emc/vmax/metadata.py rename to cinder/volume/drivers/dell_emc/powermax/metadata.py index 026840024a6..9818a015551 100644 --- a/cinder/volume/drivers/dell_emc/vmax/metadata.py +++ b/cinder/volume/drivers/dell_emc/powermax/metadata.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -24,7 +24,7 @@ from oslo_log import log as logging from cinder.objects import volume from cinder import version -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import utils LOG = logging.getLogger(__name__) CLEANUP_LIST = ['masking_view', 'child_storage_group', 'parent_storage_group', 'initiator_group', 'port_group', 'storage_group'] @@ -46,8 +46,8 @@ def debug_required(func): return func_wrapper -class VMAXVolumeMetadata(object): - """Gathers VMAX specific volume information. +class PowerMaxVolumeMetadata(object): + """Gathers PowerMax/VMAX specific volume information. Also gathers Unisphere, Microcode OS/distribution and python versions. """ @@ -55,7 +55,7 @@ class VMAXVolumeMetadata(object): def __init__(self, rest, version, is_debug): self.version_dict = {} self.rest = rest - self.utils = utils.VMAXUtils() + self.utils = utils.PowerMaxUtils() self.volume_trace_list = [] self.is_debug = is_debug self.vmax_driver_version = version @@ -137,7 +137,7 @@ class VMAXVolumeMetadata(object): self._update_info_from_version_info() def _update_vmax_info(self, serial_number): - """Update VMAX info. + """Update PowerMax/VMAX info. :param serial_number: the serial number of the array """ @@ -583,7 +583,7 @@ class VMAXVolumeMetadata(object): :param volume: volume object :param rep_info_dict: information gathered from replication - :param device_id: the VMAX device id + :param device_id: the PowerMax/VMAX device id :param extra_specs: the extra specs """ operation = "manage_existing_volume" @@ -632,11 +632,11 @@ class VMAXVolumeMetadata(object): :param volume_id: volume identifier :param volume_size: volume size - :param device_id: the VMAX device id - :param array: the VMAX serialnumber - :param srp: VMAX SRP + :param device_id: the PowerMax/VMAX device id + :param array: the PowerMax/VMAX serialnumber + :param srp: PowerMax/VMAX SRP :param target_slo: volume name - :param target_workload: the VMAX device id + :param target_workload: the PowerMax/VMAX device id :param is_rep_enabled: replication enabled flag :param rep_mode: replication mode :param is_compression_disabled: compression disabled flag diff --git a/cinder/volume/drivers/dell_emc/vmax/provision.py b/cinder/volume/drivers/dell_emc/powermax/provision.py similarity index 98% rename from cinder/volume/drivers/dell_emc/vmax/provision.py rename to cinder/volume/drivers/dell_emc/powermax/provision.py index 778a893f800..d6b368b5691 100644 --- a/cinder/volume/drivers/dell_emc/vmax/provision.py +++ b/cinder/volume/drivers/dell_emc/powermax/provision.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -21,7 +21,7 @@ from oslo_service import loopingcall from cinder import coordination from cinder import exception from cinder.i18n import _ -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import utils LOG = logging.getLogger(__name__) @@ -30,13 +30,13 @@ UNLINK_INTERVAL = 15 UNLINK_RETRIES = 30 -class VMAXProvision(object): - """Provisioning Class for Dell EMC VMAX volume drivers. +class PowerMaxProvision(object): + """Provisioning Class for Dell EMC PowerMax volume drivers. - It supports VMAX arrays. + It supports VMAX 3, All Flash and PowerMax arrays. """ def __init__(self, rest): - self.utils = utils.VMAXUtils() + self.utils = utils.PowerMaxUtils() self.rest = rest def create_storage_group( @@ -392,7 +392,7 @@ class VMAXProvision(object): _extend_replicated_volume(rdf_group) else: self.rest.extend_volume(array, device_id, new_size, extra_specs) - LOG.debug("Extend VMAX volume took: %(delta)s H:MM:SS.", + LOG.debug("Extend PowerMax/VMAX volume took: %(delta)s H:MM:SS.", {'delta': self.utils.get_time_delta(start_time, time.time())}) diff --git a/cinder/volume/drivers/dell_emc/vmax/rest.py b/cinder/volume/drivers/dell_emc/powermax/rest.py similarity index 99% rename from cinder/volume/drivers/dell_emc/vmax/rest.py rename to cinder/volume/drivers/dell_emc/powermax/rest.py index 94d51d8a889..6aac825ec34 100644 --- a/cinder/volume/drivers/dell_emc/vmax/rest.py +++ b/cinder/volume/drivers/dell_emc/powermax/rest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -31,7 +31,7 @@ from cinder import coordination from cinder import exception from cinder.i18n import _ from cinder.utils import retry -from cinder.volume.drivers.dell_emc.vmax import utils +from cinder.volume.drivers.dell_emc.powermax import utils requests.packages.urllib3.disable_warnings(urllib_exp.InsecureRequestWarning) @@ -60,11 +60,11 @@ SUCCEEDED = 'succeeded' CREATE_VOL_STRING = "Creating new Volumes" -class VMAXRest(object): - """Rest class based on Unisphere for VMAX Rest API.""" +class PowerMaxRest(object): + """Rest class based on Unisphere for PowerMax Rest API.""" def __init__(self): - self.utils = utils.VMAXUtils() + self.utils = utils.PowerMaxUtils() self.session = None self.base_uri = None self.user = None @@ -169,14 +169,15 @@ class VMAXRest(object): self.set_rest_credentials(self.u4p_failover_targets[0]) self.u4p_failover_targets.pop(0) if self.u4p_in_failover: - LOG.warning("VMAX driver still in u4p failover mode. A " + LOG.warning("PowerMax driver still in u4p failover mode. A " "periodic check will be made to see if primary " "Unisphere comes back online for seamless " "restoration.") else: - LOG.warning("VMAX driver set to u4p failover mode. A periodic " - "check will be made to see if primary Unisphere " - "comes back online for seamless restoration.") + LOG.warning("PowerMax driver set to u4p failover mode. A " + "periodic check will be made to see if primary " + "Unisphere comes back online for seamless " + "restoration.") self.u4p_in_failover = True else: msg = _("A connection could not be established with the " @@ -639,10 +640,10 @@ class VMAXRest(object): return workload_setting def get_vmax_model(self, array): - """Get the VMAX model. + """Get the PowerMax/VMAX model. :param array: the array serial number - :return: the VMAX model + :return: the PowerMax/VMAX model """ vmax_version = '' system_uri = ("/%(version)s/system/symmetrix/%(array)s" % { @@ -1120,7 +1121,7 @@ class VMAXRest(object): job, extra_specs) def get_volume(self, array, device_id): - """Get a VMAX volume from array. + """Get a PowerMax/VMAX volume from array. :param array: the array serial number :param device_id: the volume device id @@ -1161,7 +1162,7 @@ class VMAXRest(object): return volume_dict def get_volume_list(self, array, params): - """Get a filtered list of VMAX volumes from array. + """Get a filtered list of PowerMax/VMAX volumes from array. Filter parameters are required as the unfiltered volume list could be very large and could affect performance if called often. @@ -1205,7 +1206,7 @@ class VMAXRest(object): payload, resource_name=device_id) def extend_volume(self, array, device_id, new_size, extra_specs): - """Extend a VMAX volume. + """Extend a PowerMax/VMAX volume. :param array: the array serial number :param device_id: volume device id @@ -1344,7 +1345,7 @@ class VMAXRest(object): return device_id def find_volume_identifier(self, array, device_id): - """Get the volume identifier of a VMAX volume. + """Get the volume identifier of a PowerMax/VMAX volume. :param array: array serial number :param device_id: the device id diff --git a/cinder/volume/drivers/dell_emc/vmax/utils.py b/cinder/volume/drivers/dell_emc/powermax/utils.py similarity index 97% rename from cinder/volume/drivers/dell_emc/vmax/utils.py rename to cinder/volume/drivers/dell_emc/powermax/utils.py index 1613721a7bc..4b959869be2 100644 --- a/cinder/volume/drivers/dell_emc/vmax/utils.py +++ b/cinder/volume/drivers/dell_emc/powermax/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -101,16 +101,22 @@ U4P_FAILOVER_RETRIES = 'u4p_failover_retries' U4P_FAILOVER_BACKOFF_FACTOR = 'u4p_failover_backoff_factor' U4P_FAILOVER_AUTOFAILBACK = 'u4p_failover_autofailback' U4P_FAILOVER_TARGETS = 'u4p_failover_target' +POWERMAX_ARRAY = 'powermax_array' +POWERMAX_SRP = 'powermax_srp' +POWERMAX_SERVICE_LEVEL = 'powermax_service_level' +POWERMAX_PORT_GROUPS = 'powermax_port_groups' +POWERMAX_SNAPVX_UNLINK_LIMIT = 'powermax_snapvx_unlink_limit' -class VMAXUtils(object): - """Utility class for Rest based VMAX volume drivers. +class PowerMaxUtils(object): + """Utility class for Rest based PowerMax volume drivers. - This Utility class is for VMAX volume drivers based on Unisphere Rest API. + This Utility class is for PowerMax volume drivers based on Unisphere + Rest API. """ def __init__(self): - """Utility class for Rest based VMAX volume drivers.""" + """Utility class for Rest based PowerMax volume drivers.""" def get_host_short_name(self, host_name): """Returns the short name for a given qualified host name. @@ -245,7 +251,7 @@ class VMAXUtils(object): @staticmethod def modify_snapshot_prefix(snapshot_name, manage=False, unmanage=False): - """Modify a Snapshot prefix on VMAX backend. + """Modify a Snapshot prefix on PowerMax/VMAX backend. Prepare a snapshot name for manage/unmanage snapshot process either by adding or removing 'OS-' prefix. @@ -253,7 +259,7 @@ class VMAXUtils(object): :param snapshot_name: the old snapshot backend display name :param manage: (bool) if the operation is managing a snapshot :param unmanage: (bool) if the operation is unmanaging a snapshot - :return: snapshot name ready for backend VMAX assignment + :return: snapshot name ready for backend PowerMax/VMAX assignment """ new_snap_name = None if manage: @@ -813,8 +819,8 @@ class VMAXUtils(object): """ vol_head = source_vol['volumeHeader'] - # VMAX disk geometry uses cylinders, so volume sizes are matched to - # the nearest full cylinder size: 1GB = 547cyl = 1026MB + # PowerMax/VMAX disk geometry uses cylinders, so volume sizes are + # matched to the nearest full cylinder size: 1GB = 547cyl = 1026MB if vol_head['capMB'] < 1026 or not vol_head['capGB'].is_integer(): return False @@ -857,8 +863,8 @@ class VMAXUtils(object): if not source_vol['timeFinderInfo']['snapVXSrc']: return False - # VMAX disk geometry uses cylinders, so volume sizes are matched to - # the nearest full cylinder size: 1GB = 547cyl = 1026MB + # PowerMax/VMAX disk geometry uses cylinders, so volume sizes are + # matched to the nearest full cylinder size: 1GB = 547cyl = 1026MB if (vol_head['capMB'] < 1026 or not vol_head['capGB'].is_integer()): return False diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index 889b54dbdbf..6ad78910af6 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -165,6 +165,10 @@ CONF.register_opts(volume_backend_opts, group=config.SHARED_CONF_GROUP) # new name (the dict value) for at least a cycle to allow time for deployments # to transition. MAPPING = { + 'cinder.volume.drivers.dell_emc.vmax.iscsi.VMAXISCSIDriver': + 'cinder.volume.drivers.dell_emc.powermax.iscsi.PowerMaxISCSIDriver', + 'cinder.volume.drivers.dell_emc.vmax.fc.VMAXFCDriver': + 'cinder.volume.drivers.dell_emc.powermax.fc.PowerMaxFCDriver', } diff --git a/doc/source/configuration/block-storage/drivers/dell-emc-vmax-driver.rst b/doc/source/configuration/block-storage/drivers/dell-emc-powermax-driver.rst similarity index 87% rename from doc/source/configuration/block-storage/drivers/dell-emc-vmax-driver.rst rename to doc/source/configuration/block-storage/drivers/dell-emc-powermax-driver.rst index 447a6607f68..fe9a1633664 100644 --- a/doc/source/configuration/block-storage/drivers/dell-emc-vmax-driver.rst +++ b/doc/source/configuration/block-storage/drivers/dell-emc-powermax-driver.rst @@ -1,16 +1,24 @@ -================================== -Dell EMC VMAX iSCSI and FC drivers -================================== +====================================== +Dell EMC POWERMAX iSCSI and FC drivers +====================================== -The Dell EMC VMAX drivers, ``VMAXISCSIDriver`` and ``VMAXFCDriver``, support -the use of Dell EMC VMAX storage arrays with the Cinder Block Storage project. -They both provide equivalent functions and differ only in support for their -respective host attachment methods. +The Dell EMC PowerMax drivers, ``PowerMaxISCSIDriver`` and ``PowerMaxFCDriver``, +support the use of Dell EMC PowerMax and VMAX storage arrays with the Cinder +Block Storage project. They both provide equivalent functions and differ only +in support for their respective host attachment methods. -The drivers perform volume operations by communicating with the back-end VMAX -storage management software. They use the Requests HTTP library to communicate -with a Unisphere for VMAX instance, using a RESTAPI interface in the backend -to perform VMAX storage operations. +The drivers perform volume operations by communicating with the back-end +PowerMax storage management software. They use the Requests HTTP library to +communicate with a Unisphere for PowerMax instance, using a RESTAPI interface +in the backend to perform PowerMax and VMAX storage operations. + +.. note:: + + While ``PowerMax`` will be used throughout this document, it will be used + to collectively categorize the following supported arrays, PowerMax 2000, + 8000, VMAX All Flash 250F, 450F, 850F and 950F and VMAX Hybrid. Please note + That we will no longer be supporting the VMAX Hybrid in the ``T`` release + of OpenStack. .. note:: @@ -20,17 +28,18 @@ to perform VMAX storage operations. leveraged workload i.e. DSS, DSS_REP, OLTP and OLTP_REP, attaching and detaching will no longer work and the volume type will be unusable. Refrain from upgrading to PowerMax OS 5978 or greater on an All Flash - until a fix is merged. Please contact your Dell EMC VMAX customer support - representative if in any doubt. + until a fix is merged. Please contact your Dell EMC PowerMax customer + support representative if in any doubt. System requirements and licensing ================================= -The Dell EMC VMAX Cinder driver supports the VMAX-3 hybrid series, VMAX -All-Flash series and the PowerMax arrays. +The Dell EMC PowerMax Cinder driver supports the VMAX-3 hybrid series, VMAX +All-Flash series and the PowerMax arrays. Please note we will be no longer +supporting the VMAX hybrid series in the ``T`` release of OpenStack. The array operating system software, Solutions Enabler 9.0.x series, and -Unisphere for PowerMax 9.0.x series are required to run Dell EMC VMAX +Unisphere for PowerMax 9.0.x series are required to run Dell EMC PowerMax Cinder driver. Download Solutions Enabler and Unisphere from the Dell EMC's support web site @@ -38,8 +47,8 @@ Download Solutions Enabler and Unisphere from the Dell EMC's support web site and Configuration Guide`` and ``Dell EMC Unisphere for PowerMax Installation Guide`` at ``support.emc.com``. -Required VMAX software suites for OpenStack -------------------------------------------- +Required PowerMax software suites for OpenStack +----------------------------------------------- There are five Dell EMC Software Suites sold with the VMAX Hybrid arrays: @@ -49,17 +58,17 @@ There are five Dell EMC Software Suites sold with the VMAX Hybrid arrays: - Remote Replication Suite - Total Productivity Pack -The Dell EMC VMAX Cinder driver requires the Advanced Suite and the Local +The Dell EMC PowerMax Cinder driver requires the Advanced Suite and the Local Replication Suite or the Total Productivity Pack (it includes the Advanced Suite and the Local Replication Suite) for the VMAX Hybrid. -Using VMAX Remote Replication functionality will also require the Remote +Using PowerMax Remote Replication functionality will also require the Remote Replication Suite. For full functionality including SRDF for the VMAX All Flash, the FX package, or the F package plus the SRDF ``a la carte`` add on is required. -The storage system also requires a Unisphere for VMAX (SMC) eLicence. +The storage system also requires a Unisphere for PowerMax (SMC) eLicence. Each are licensed separately. For further details on how to get the relevant license(s), reference eLicensing Support below. @@ -68,7 +77,7 @@ relevant license(s), reference eLicensing Support below. eLicensing support ------------------ -To activate your entitlements and obtain your VMAX license files, visit the +To activate your entitlements and obtain your PowerMax license files, visit the Service Center on ``_, as directed on your License Authorization Code (LAC) letter emailed to you. @@ -92,7 +101,7 @@ Authorization Code (LAC) letter emailed to you. Supported operations ==================== -VMAX drivers support these operations: +PowerMax drivers support these operations: - Create, list, delete, attach, and detach volumes - Create, list, and delete volume snapshots @@ -112,7 +121,7 @@ VMAX drivers support these operations: - Manage and unmanage volumes and snapshots - List Manageable Volumes/Snapshots -VMAX drivers also support the following features: +PowerMax drivers also support the following features: - Dynamic masking view creation - Dynamic determination of the target iSCSI IP address @@ -137,15 +146,15 @@ VMAX drivers also support the following features: compressed. -VMAX naming conventions -======================= +PowerMax naming conventions +=========================== Masking view names ------------------ -Masking views are dynamically created by the VMAX FC and iSCSI drivers using -the following naming conventions. ``[protocol]`` is either ``I`` for volumes -attached over iSCSI or ``F`` for volumes attached over Fiber Channel. +Masking views are dynamically created by the PowerMax FC and iSCSI drivers +using the following naming conventions. ``[protocol]`` is either ``I`` for +volumes attached over iSCSI or ``F`` for volumes attached over Fiber Channel. .. code-block:: text @@ -154,11 +163,11 @@ attached over iSCSI or ``F`` for volumes attached over Fiber Channel. Initiator group names --------------------- -For each host that is attached to VMAX volumes using the drivers, an initiator -group is created or re-used (per attachment type). All initiators of the -appropriate type known for that host are included in the group. At each new -attach volume operation, the VMAX driver retrieves the initiators (either -WWNNs or IQNs) from OpenStack and adds or updates the contents of the +For each host that is attached to PowerMax volumes using the drivers, an +initiator group is created or re-used (per attachment type). All initiators +of the appropriate type known for that host are included in the group. At +each new attach volume operation, the PowerMax driver retrieves the initiators +(either WWNNs or IQNs) from OpenStack and adds or updates the contents of the Initiator Group as required. Names are of the following format. ``[protocol]`` is either ``I`` for volumes attached over iSCSI or ``F`` for volumes attached over Fiber Channel. @@ -169,13 +178,13 @@ over Fiber Channel. .. note:: - Hosts attaching to OpenStack managed VMAX storage cannot also attach to - storage on the same VMAX that are not managed by OpenStack. + Hosts attaching to OpenStack managed PowerMax storage cannot also attach to + storage on the same PowerMax that are not managed by OpenStack. FA port groups -------------- -VMAX array FA ports to be used in a new masking view are retrieved from the +PowerMax array FA ports to be used in a new masking view are retrieved from the port group provided as the extra spec on the volume type, or chosen from the list provided in the Dell EMC configuration file. @@ -187,7 +196,7 @@ storage group (if it exists) or a new storage group is created and the volume is then added. Storage groups contain volumes created from a pool, attached to a single host, over a single connection type (iSCSI or FC). ``[protocol]`` is either ``I`` for volumes attached over iSCSI or ``F`` for volumes attached -over Fiber Channel. VMAX Cinder driver utilizes cascaded storage groups - +over Fiber Channel. PowerMax Cinder driver utilizes cascaded storage groups - a ``parent`` storage group which is associated with the masking view, which contains ``child`` storage groups for each configured SRP/slo/workload/compression-enabled or disabled/replication-enabled or @@ -218,8 +227,8 @@ Child storage groups: is NONE -VMAX Driver Integration -======================= +PowerMax Driver Integration +=========================== 1. Prerequisites ---------------- @@ -237,7 +246,7 @@ VMAX Driver Integration .. note:: - You must discover storage arrays before you can use the VMAX drivers. + You must discover storage arrays before you can use the PowerMax drivers. Follow instructions in ```Dell EMC Solutions Enabler 9.0.x Installation and Configuration Guide`` on ``support.emc.com`` for more details. @@ -247,26 +256,26 @@ VMAX Driver Integration - i.e., on the same server running Solutions Enabler; on a server connected to the Solutions Enabler server; or using the eManagement container application (containing Solutions Enabler and Unisphere for - VMAX). See ``Dell EMC Solutions Enabler 9.0.x Installation and Configuration + PowerMax). See ``Dell EMC Solutions Enabler 9.0.x Installation and Configuration Guide`` at ``support.emc.com``. -2. FC Zoning with VMAX ----------------------- +2. FC Zoning with PowerMax +-------------------------- Zone Manager is required when there is a fabric between the host and array. This is necessary for larger configurations where pre-zoning would be too complex and open-zoning would raise security concerns. -3. iSCSI with VMAX ------------------- +3. iSCSI with PowerMax +---------------------- - Make sure the ``iscsi-initiator-utils`` package is installed on all Compute nodes. .. note:: - You can only ping the VMAX iSCSI target ports when there is a valid masking + You can only ping the PowerMax iSCSI target ports when there is a valid masking view. An attach operation creates this masking view. @@ -274,13 +283,13 @@ complex and open-zoning would raise security concerns. ----------------------------------------- .. config-table:: - :config-target: VMAX + :config-target: PowerMax - cinder.volume.drivers.dell_emc.vmax.common + cinder.volume.drivers.dell_emc.powermax.common .. note:: - For security and backend uniformity, the use of the XML file for VMAX + For security and backend uniformity, the use of the XML file for PowerMax backend configuration was deprecated in Queens and removed entirely in Rocky. @@ -293,11 +302,11 @@ complex and open-zoning would raise security concerns. .. note:: - VMAX ``PortGroups`` must be pre-configured to expose volumes managed + PowerMax ``PortGroups`` must be pre-configured to expose volumes managed by the array. Port groups can be supplied in the ``cinder.conf``, or can be specified as an extra spec ``storagetype:portgroupname`` on a volume type. The latter gives the user more control. When a dynamic - masking view is created by the VMAX driver, if there is no port group + masking view is created by the PowerMax driver, if there is no port group specified as an extra specification, the port group is chosen randomly from the PortGroup list, to evenly distribute load across the set of groups provided. @@ -310,13 +319,13 @@ complex and open-zoning would raise security concerns. Workload is NONE for PowerMax and any All Flash with PowerMax OS (5978) or greater. - +-----------------+------------------------+---------+----------+ - | VMAX parameter | cinder.conf parameter | Default | Required | - +=================+========================+=========+==========+ - | ServiceLevel | vmax_service_level | None | No | - +-----------------+------------------------+---------+----------+ - | Workload | vmax_workload | None | No | - +-----------------+------------------------+---------+----------+ + +--------------------+------------------------+---------+----------+ + | PowerMAX parameter | cinder.conf parameter | Default | Required | + +====================+========================+=========+==========+ + | ServiceLevel | vmax_service_level | None | No | + +--------------------+------------------------+---------+----------+ + | Workload | vmax_workload | None | No | + +--------------------+------------------------+---------+----------+ Configure Block Storage in cinder.conf @@ -327,8 +336,8 @@ complex and open-zoning would raise security concerns. enabled_backends = CONF_GROUP_ISCSI, CONF_GROUP_FC [CONF_GROUP_ISCSI] - volume_driver = cinder.volume.drivers.dell_emc.vmax.iscsi.VMAXISCSIDriver - volume_backend_name = VMAX_ISCSI + volume_driver = cinder.volume.drivers.dell_emc.powermax.iscsi.PowerMaxISCSIDriver + volume_backend_name = POWERMAX_ISCSI vmax_port_groups = [OS-ISCSI-PG] san_ip = 10.10.10.10 san_login = my_username @@ -338,8 +347,8 @@ complex and open-zoning would raise security concerns. [CONF_GROUP_FC] - volume_driver = cinder.volume.drivers.dell_emc.vmax.fc.VMAXFCDriver - volume_backend_name = VMAX_FC + volume_driver = cinder.volume.drivers.dell_emc.powermax.fc.PowerMaxFCDriver + volume_backend_name = POWERMAX_FC vmax_port_groups = [OS-FC-PG] san_ip = 10.10.10.10 san_login = my_username @@ -369,8 +378,8 @@ complex and open-zoning would raise security concerns. Where ``my_unisphere_host`` is the hostname of the unisphere instance and ``my_unisphere_host.pem`` is the name of the .pem file. -#. Add this path to ``cinder.conf`` under the VMAX backend stanza and set SSL - verify to True +#. Add this path to ``cinder.conf`` under the PowerMax backend stanza and set + SSL verify to True .. code-block:: console @@ -401,8 +410,8 @@ complex and open-zoning would raise security concerns. # export REQUESTS_CA_BUNDLE = /etc/ssl/certs/ca-certificates.crt -#. OPTIONAL: Set cert verification to ``true`` under the VMAX backend stanza in - ``cinder.conf``: +#. OPTIONAL: Set cert verification to ``true`` under the PowerMax backend + stanza in ``cinder.conf``: .. code-block:: console @@ -440,24 +449,24 @@ complex and open-zoning would raise security concerns. .. code-block:: console - $ openstack volume type create VMAX_ISCSI_SILVER_OLTP + $ openstack volume type create POWERMAX_ISCSI_SILVER_OLTP $ openstack volume type set --property volume_backend_name=ISCSI_backend \ --property pool_name=Silver+OLTP+SRP_1+000123456789 \ --property storagetype:portgroupname=OS-PG2 \ - VMAX_ISCSI_SILVER_OLTP - $ openstack volume type create VMAX_FC_DIAMOND_DSS + POWERMAX_ISCSI_SILVER_OLTP + $ openstack volume type create POWERMAX_FC_DIAMOND_DSS $ openstack volume type set --property volume_backend_name=FC_backend \ --property pool_name=Diamond+DSS+SRP_1+000123456789 \ --property storagetype:portgroupname=OS-PG1 \ - VMAX_FC_DIAMOND_DSS + POWERMAX_FC_DIAMOND_DSS By issuing these commands, the Block Storage volume type - ``VMAX_ISCSI_SILVER_OLTP`` is associated with the ``ISCSI_backend``, a Silver - Service Level, and an OLTP workload. + ``POWERMAX_ISCSI_SILVER_OLTP`` is associated with the ``ISCSI_backend``, + a Silver Service Level, and an OLTP workload. - The type ``VMAX_FC_DIAMOND_DSS`` is associated with the ``FC_backend``, a - Diamond Service Level, and a DSS workload. + The type ``POWERMAX_FC_DIAMOND_DSS`` is associated with the ``FC_backend``, + a Diamond Service Level, and a DSS workload. The ``ServiceLevel`` manages the underlying storage to provide expected performance. Setting the ``ServiceLevel`` to ``None`` means that non-FAST @@ -502,13 +511,13 @@ should be increased so calls will not timeout prematurely. In the example below, the driver checks every 3 seconds for the status of the job. It will continue checking for 200 retries before it times out. -Add the following lines to the VMAX backend in the cinder.conf: +Add the following lines to the PowerMax backend in the cinder.conf: .. code-block:: console [CONF_GROUP_ISCSI] - volume_driver = cinder.volume.drivers.dell_emc.vmax.iscsi.VMAXISCSIDriver - volume_backend_name = VMAX_ISCSI + volume_driver = cinder.volume.drivers.dell_emc.powermax.iscsi.PowerMaxISCSIDriver + volume_backend_name = POWERMAX_ISCSI vmax_port_groups = [OS-ISCSI-PG] san_ip = 10.10.10.10 san_login = my_username @@ -522,15 +531,16 @@ Add the following lines to the VMAX backend in the cinder.conf: ------------------------------ This supports one way initiator CHAP authentication functionality into the -VMAX backend. With CHAP one-way authentication, the storage array challenges -the host during the initial link negotiation process and expects to receive -a valid credential and CHAP secret in response. When challenged, the host -transmits a CHAP credential and CHAP secret to the storage array. The storage -array looks for this credential and CHAP secret which stored in the host -initiator's initiator group (IG) information in the ACLX database. Once a -positive authentication occurs, the storage array sends an acceptance message -to the host. However, if the storage array fails to find any record of the -credential/secret pair, it sends a rejection message, and the link is closed. +PowerMax backend. With CHAP one-way authentication, the storage array +challenges the host during the initial link negotiation process and expects +to receive a valid credential and CHAP secret in response. When challenged, +the host transmits a CHAP credential and CHAP secret to the storage array. +The storagearray looks for this credential and CHAP secret which stored in +the host initiator's initiator group (IG) information in the ACLX database. +Once a positive authentication occurs, the storage array sends an acceptance +message to the host. However, if the storage array fails to find any record +of the credential/secret pair, it sends a rejection message, and the link is +closed. Assumptions, Restrictions and Pre-Requisites ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -559,7 +569,7 @@ Assumptions, Restrictions and Pre-Requisites Settings and Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~ -#. Set the configuration in the VMAX backend group in cinder.conf using the +#. Set the configuration in the PowerMax backend group in cinder.conf using the following parameters and restart cinder. +-----------------------+-------------------------+-------------------+ @@ -574,9 +584,9 @@ Settings and Configuration .. code-block:: ini - [VMAX_ISCSI] - volume_driver = cinder.volume.drivers.dell_emc.vmax.iscsi.VMAXISCSIDriver - volume_backend_name = VMAX_ISCSI + [POWERMAX_ISCSI] + volume_driver = cinder.volume.drivers.dell_emc.powermax.iscsi.PowerMaxISCSIDriver + volume_backend_name = POWERMAX_ISCSI san_ip = 10.10.10.10 san_login = my_u4v_username san_password = my_u4v_password @@ -645,21 +655,22 @@ limits the following: QoS enforcement in Cinder is done either at the hypervisor (front end), the storage subsystem (back end), or both. This section focuses on QoS -limits that are enforced by either the VMAX backend and the hypervisor -front end interchangeably or just back end (Vendor Specific). The VMAX driver -offers support for Total bytes/sec limit in throughput and Total IOPS/sec -limit of IOPS. +limits that are enforced by either the PowerMax backend and the hypervisor +front end interchangeably or just back end (Vendor Specific). The PowerMax +driver offers support for Total bytes/sec limit in throughput and Total +IOPS/sec limit of IOPS. -The VMAX driver supports the following attributes that are front end/back end -agnostic +The PowerMax driver supports the following attributes that are front +end/back end agnostic - total_iops_sec - Maximum IOPs (in I/Os per second). Valid values range from 100 IO/Sec to 100,000 IO/sec. - total_bytes_sec - Maximum bandwidth (throughput) in bytes per second. Valid values range from 1048576 bytes (1MB) to 104857600000 bytes (100, 000MB) -The VMAX driver offers the following attribute that is vendor specific to the -VMAX and dependent on the total_iops_sec and/or total_bytes_sec being set. +The PowerMax driver offers the following attribute that is vendor specific to +the PowerMax and dependent on the total_iops_sec and/or total_bytes_sec being +set. - Dynamic Distribution - Enables/Disables dynamic distribution of host I/O limits. Possible values are: @@ -676,7 +687,7 @@ VMAX and dependent on the total_iops_sec and/or total_bytes_sec being set. USE CASE 1 - Default values ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Prerequisites - VMAX +Prerequisites - PowerMax - Host I/O Limit (MB/Sec) - No Limit - Host I/O Limit (IO/Sec) - No Limit @@ -716,7 +727,7 @@ Prerequisites - VMAX $ openstack volume create --size 1 --type my_volume_type my_volume -**Outcome - VMAX (storage group)** +**Outcome - PowerMax (storage group)** - Host I/O Limit (MB/Sec) - 100 - Host I/O Limit (IO/Sec) - 500 @@ -730,7 +741,7 @@ above. USE CASE 2 - Preset limits ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Prerequisites - VMAX +Prerequisites - PowerMax - Host I/O Limit (MB/Sec) - 2000 - Host I/O Limit (IO/Sec) - 2000 @@ -777,7 +788,7 @@ Prerequisites - VMAX $ openstack server add volume my_volume my_instance -**Outcome - VMAX (storage group)** +**Outcome - PowerMax (storage group)** - Host I/O Limit (MB/Sec) - 100 - Host I/O Limit (IO/Sec) - 500 @@ -854,7 +865,7 @@ The output of the command contains the xml below. It is found between the USE CASE 3 - Preset limits ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Prerequisites - VMAX +Prerequisites - PowerMax - Host I/O Limit (MB/Sec) - 100 - Host I/O Limit (IO/Sec) - 500 @@ -894,7 +905,7 @@ Prerequisites - VMAX $ openstack volume create --size 1 --type my_volume_type my_volume -**Outcome - VMAX (storage group)** +**Outcome - PowerMax (storage group)** - Host I/O Limit (MB/Sec) - 100 - Host I/O Limit (IO/Sec) - 500 @@ -908,7 +919,7 @@ Volume is created against volume type and QOS is enforced with the parameters ab USE CASE 4 - Default values ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Prerequisites - VMAX +Prerequisites - PowerMax - Host I/O Limit (MB/Sec) - No Limit - Host I/O Limit (IO/Sec) - No Limit @@ -943,7 +954,7 @@ Prerequisites - VMAX $ openstack volume create --size 1 --type my_volume_type my_volume -**Outcome - VMAX (storage group)** +**Outcome - PowerMax (storage group)** - Host I/O Limit (MB/Sec) - No Limit - Host I/O Limit (IO/Sec) - No Limit @@ -996,7 +1007,7 @@ performance. Log in as a privileged user and make the following changes to .. code-block:: vim devices { - # Device attributed for EMC VMAX + # Device attributed for EMC PowerMax device { vendor "EMC" product "SYMMETRIX" @@ -1053,7 +1064,7 @@ On Compute (Nova) node, add the following flag in the ``[libvirt]`` section of volume_use_multipath = True On Cinder controller node, iSCSI MPIO can be set globally in the -[DEFAULT] section or set individually in the VMAX backend stanza in +[DEFAULT] section or set individually in the PowerMax backend stanza in :file:`/etc/cinder/cinder.conf`: .. code-block:: ini @@ -1065,8 +1076,8 @@ Restart ``nova-compute`` and ``cinder-volume`` services after the change. Verify you have multiple initiators available on the compute node for I/O ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -#. Create a 3GB VMAX volume. -#. Create an instance from image out of native LVM storage or from VMAX +#. Create a 3GB PowerMax volume. +#. Create an instance from image out of native LVM storage or from PowerMax storage, for example, from a bootable volume #. Attach the 3GB volume to the new instance: @@ -1111,7 +1122,7 @@ uncompressed. Use case 1 - Compression disabled create, attach, detach, and delete volume ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -#. Create a new volume type called ``VMAX_COMPRESSION_DISABLED``. +#. Create a new volume type called ``POWERMAX_COMPRESSION_DISABLED``. #. Set an extra spec ``volume_backend_name``. #. Set a new extra spec ``storagetype:disablecompression = True``. #. Create a new volume. @@ -1134,12 +1145,12 @@ Use case 2 - Retype from compression disabled to compression enabled ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #. Repeat steps 1-4 of Use case 1. -#. Create a new volume type. For example ``VMAX_COMPRESSION_ENABLED``. +#. Create a new volume type. For example ``POWERMAX_COMPRESSION_ENABLED``. #. Set extra spec ``volume_backend_name`` as before. #. Set the new extra spec's compression as ``storagetype:disablecompression = False`` or DO NOT set this extra spec. -#. Retype from volume type ``VMAX_COMPRESSION_DISABLED`` to - ``VMAX_COMPRESSION_ENABLED``. +#. Retype from volume type ``POWERMAX_COMPRESSION_DISABLED`` to + ``POWERMAX_COMPRESSION_ENABLED``. #. Check in Unisphere or symcli to see if the volume exists in storage group ``OS----SG``, and compression is enabled on that storage group. @@ -1173,22 +1184,22 @@ of live migration are: read-only devices such as CD-ROMs and Configuration Drive (config_drive). - Volume-backed live migration. Instances are backed by volumes rather than - ephemeral disk. For VMAX volume-backed live migration, shared storage + ephemeral disk. For PowerMax volume-backed live migration, shared storage is required. -The VMAX driver supports shared volume-backed live migration. +The PowerMax driver supports shared volume-backed live migration. Architecture ~~~~~~~~~~~~ -In VMAX, A volume cannot belong to two or more FAST storage groups at the +In PowerMax, A volume cannot belong to two or more FAST storage groups at the same time. To get around this limitation we leverage both cascaded storage groups and a temporary non FAST storage group. A volume can remain 'live' if moved between masking views that have the same initiator group and port groups which preserves the host path. -During live migration, the following steps are performed by the VMAX plugin +During live migration, the following steps are performed by the PowerMax driver on the volume: #. Within the originating masking view, the volume is moved from the FAST @@ -1345,7 +1356,7 @@ nodes. The following were also used in live migration. 14. Multi-attach support ------------------------ -VMAX cinder driver supports the ability to attach a volume to multiple +PowerMax cinder driver supports the ability to attach a volume to multiple hosts/servers simultaneously. Please see https://docs.openstack.org/cinder/latest/admin/blockstorage-volume-multiattach.html for configuration information. @@ -1353,7 +1364,7 @@ for configuration information. Multi-attach Architecture ~~~~~~~~~~~~~~~~~~~~~~~~~ -In VMAX, a volume cannot belong to two or more FAST storage groups at the same +In PowerMax, a volume cannot belong to two or more FAST storage groups at the same time. This can cause issues when we are attaching a volume to multiple instances on different hosts. To get around this limitation, we leverage both cascaded storage groups and non-FAST storage groups (i.e. a storage group with @@ -1411,7 +1422,7 @@ https://docs.openstack.org/cinder/latest/configuration/block-storage/volume-encr 16. Volume metadata in logs --------------------------- -If debug is enabled in the default section of the cinder.conf, VMAX Cinder +If debug is enabled in the default section of the cinder.conf, PowerMax Cinder driver will log additional volume information in the Cinder volume log, on each successful operation. The facilitates bridging the gap between OpenStack and the Array by tracing and describing the volume from a VMAX/ @@ -1456,8 +1467,8 @@ Configure the source and target arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #. Configure an SRDF group between the chosen source and target - arrays for the VMAX Cinder driver to use. The source array must correspond - with the 'vmax_array' entry in the cinder.conf. + arrays for the PowerMax Cinder driver to use. The source array must + correspond with the 'vmax_array' entry in the cinder.conf. #. Select both the director and the ports for the SRDF emulation to use on both sides. Bear in mind that network topology is important when choosing director endpoints. Supported modes are `Synchronous`, `Asynchronous`, @@ -1486,7 +1497,7 @@ Configure the source and target arrays https://www.emc.com/collateral/technical-documentation/h14556-vmax3-srdf-metro-overview-and-best-practices-tech-note.pdf #. Enable replication in ``/etc/cinder/cinder.conf``. - To enable the replication functionality in VMAX Cinder driver, it is + To enable the replication functionality in PowerMax Cinder driver, it is necessary to create a replication volume-type. The corresponding back-end stanza in the ``cinder.conf`` for this volume-type must then include a ``replication_device`` parameter. This parameter defines a @@ -1495,16 +1506,16 @@ Configure the source and target arrays .. code-block:: console - enabled_backends = VMAX_FC_REPLICATION - [VMAX_FC_REPLICATION] - volume_driver = cinder.volume.drivers.dell_emc.vmax_fc.VMAXFCDriver + enabled_backends = POWERMAX_FC_REPLICATION + [POWERMAX_FC_REPLICATION] + volume_driver = cinder.volume.drivers.dell_emc.powermax.fc.PowerMaxFCDriver san_ip = 10.10.10.10 san_login = my_u4v_username san_password = my_u4v_password vmax_srp = SRP_1 vmax_array = 000123456789 vmax_port_groups = [OS-FC-PG] - volume_backend_name = VMAX_FC_REPLICATION + volume_backend_name = POWERMAX_FC_REPLICATION replication_device = target_device_id:000197811111, remote_port_group:os-failover-pg, remote_pool:SRP_1, @@ -1520,11 +1531,11 @@ Configure the source and target arrays (separated by commas) in cinder.conf. They are displayed on separated lines above for readiblity. - * ``target_device_id`` is a unique VMAX array serial number of the target - array. For full failover functionality, the source and target VMAX arrays + * ``target_device_id`` is a unique PowerMax array serial number of the target + array. For full failover functionality, the source and target PowerMax arrays must be discovered and managed by the same U4V server. - * ``remote_port_group`` is the name of a VMAX port group that has been + * ``remote_port_group`` is the name of a PowerMax port group that has been pre-configured to expose volumes managed by this backend in the event of a failover. Make sure that this portgroup contains either all FC or all iSCSI port groups (for a given back end), as appropriate for the @@ -1532,8 +1543,8 @@ Configure the source and target arrays * ``remote_pool`` is the unique pool name for the given target array. - * ``rdf_group_label`` is the name of a VMAX SRDF group that has been pre-configured - between the source and target arrays. + * ``rdf_group_label`` is the name of a PowerMax SRDF group that has been + pre-configured between the source and target arrays. * ``allow_extend`` is a flag for allowing the extension of replicated volumes. To extend a volume in an SRDF relationship, this relationship must first be @@ -1570,21 +1581,21 @@ Configure the source and target arrays configured), no service level will be applied. .. note:: - The VMAX Cinder drivers can support a single replication target per + The PowerMax Cinder drivers can support a single replication target per back-end, that is we do not support Concurrent SRDF or Cascaded SRDF. Ensure there is only a single ``replication_device`` entry per back-end stanza. #. Create a ``replication-enabled`` volume type. Once the - ``replication_device`` parameter has been entered in the VMAX + ``replication_device`` parameter has been entered in the PowerMax backend entry in the ``cinder.conf``, a corresponding volume type needs to be created ``replication_enabled`` property set. See - above ``Setup VMAX drivers`` for details. + above ``Setup PowerMax drivers`` for details. .. code-block:: console # openstack volume type set --property replication_enabled=" True" \ - VMAX_FC_REPLICATION + POWERMAX_FC_REPLICATION Volume replication interoperability with other features @@ -1594,7 +1605,7 @@ Most features are supported, except for the following: * Replication Group operations are available for volumes in Synchronous mode only. -* Storage-assisted retype operations on replication-enabled VMAX volumes +* Storage-assisted retype operations on replication-enabled PowerMax volumes (moving from a non-replicated type to a replicated-type and vice-versa. Moving to another service level/workload combination, for example) are not supported. @@ -1629,14 +1640,14 @@ host command to failover to the configured target: .. code-block:: console - # cinder failover-host cinder_host@VMAX_FC_REPLICATION + # cinder failover-host cinder_host@POWERMAX_FC_REPLICATION If the primary array becomes available again, you can initiate a failback using the same command and specifying ``--backend_id default``: .. code-block:: console - # cinder failover-host cinder_host@VMAX_FC_REPLICATION --backend_id default + # cinder failover-host cinder_host@POWERMAX_FC_REPLICATION --backend_id default .. note:: @@ -1682,7 +1693,7 @@ Volume retype - storage assisted volume migration -------------------------------------------------- Volume retype with storage assisted migration is supported now for -VMAX3 arrays. Cinder requires that for storage assisted migration, a +PowerMax arrays. Cinder requires that for storage assisted migration, a volume cannot be retyped across backends. For using storage assisted volume retype, follow these steps: @@ -1690,7 +1701,7 @@ retype, follow these steps: another, use volume retype with the migration-policy to on-demand. The target volume type should have the same volume_backend_name configured and should have the desired pool_name to which you are trying to retype to - (please refer to ``Setup VMAX Drivers`` for details). + (please refer to ``Setup PowerMax Drivers`` for details). .. code-block:: console @@ -1711,7 +1722,7 @@ Generic volume group support Generic volume group operations are performed through the CLI using API version 3.1x of the Cinder API. Generic volume groups are multi-purpose -groups which can be used for various features. The VMAX plugin supports +groups which can be used for various features. The PowerMax driver supports consistent group snapshots and replication groups. Consistent group snapshots allows the user to take group snapshots which are consistent based on the group specs. Replication groups allow for/ @@ -1735,14 +1746,14 @@ while creating the group. .. code-block:: console # openstack volume type set --property replication_enabled=" True" / - VMAX_REPLICATION + POWERMAX_REPLICATION If this key is not set on the group-spec or volume type, then the generic -volume group will be created/managed by Cinder (not the VMAX plugin). +volume group will be created/managed by Cinder (not the PowerMax driver). .. note:: - The consistent group snapshot should not be confused with the VMAX + The consistent group snapshot should not be confused with the PowerMax consistency group which is an SRDF construct. Replication groups @@ -1766,7 +1777,7 @@ without failing over the entire host. See below for usage. Storage Group Names ~~~~~~~~~~~~~~~~~~~ -Storage groups are created on the VMAX as a result of creation of generic +Storage groups are created on the PowerMax as a result of creation of generic volume groups. These storage groups follow a different naming convention and are of the following format depending upon whether the groups have a name. @@ -1955,7 +1966,7 @@ the same format: +----------------+-------------------------------------------------------------+ | SRP | The Storage Resource Pool configured for use by the backend | +----------------+-------------------------------------------------------------+ - | array_id | The VMAX serial number (12 digit numerical) | + | array_id | The PowerMax serial number (12 digit numerical) | +----------------+-------------------------------------------------------------+ @@ -1979,18 +1990,18 @@ Command Example: .. code-block:: console - $ cinder manage --name vmax_managed_volume --volume-type VMAX_ISCSI_DIAMOND \ - --availability-zone nova demo@VMAX_ISCSI_DIAMOND#Diamond+SRP_1+111111111111 031D8 + $ cinder manage --name vmax_managed_volume --volume-type POWERMAX_ISCSI_DIAMOND \ + --availability-zone nova demo@POWERMAX_ISCSI_DIAMOND#Diamond+SRP_1+111111111111 031D8 After the above command has been run, the volume will be available for use in -the same way as any other OpenStack VMAX volume. +the same way as any other OpenStack PowerMax volume. .. note:: An unmanaged volume with a prefix of 'OS-' in its identifier name cannot be managed into OpenStack, as this is a reserved keyword for managed volumes. If the identifier name has this prefix, an exception will be thrown by the - VMAX driver on a manage operation. + PowerMax driver on a manage operation. Managing Volumes with Replication Enabled @@ -1999,19 +2010,19 @@ Managing Volumes with Replication Enabled Whilst it is not possible to manage volumes into OpenStack that are part of a SRDF relationship, it is possible to manage a volume into OpenStack and enable replication at the same time. This is done by having a replication -enabled VMAX volume type (for more information see section Volume Replication) -during the manage volume process you specify the replication volume type as -the chosen volume type. Once managed, replication will be enabled for that -volume. +enabled PowerMax volume type (for more information see section Volume +Replication) during the manage volume process you specify the replication +volume type as the chosen volume type. Once managed, replication will be +enabled for that volume. Unmanage Volume ~~~~~~~~~~~~~~~ Unmanaging a volume is not the same as deleting a volume. When a volume is -deleted from OpenStack, it is also deleted from the VMAX at the same time. +deleted from OpenStack, it is also deleted from the PowerMax at the same time. Unmanaging a volume is the process whereby a volume is removed from OpenStack -but it remains for further use on the VMAX. The volume can also be managed +but it remains for further use on the PowerMax. The volume can also be managed back into OpenStack at a later date using the process discussed in the previous section. Unmanaging volume is carried out using the Cinder unmanage CLI command: @@ -2037,7 +2048,7 @@ the volume is no longer managed by OpenStack. Manage/Unmanage Snapshots ------------------------- -Users can manage VMAX SnapVX snapshots into OpenStack if the source volume +Users can manage PowerMax SnapVX snapshots into OpenStack if the source volume already exists in Cinder. Similarly, users will be able to unmanage OpenStack snapshots to remove them from Cinder but keep them on the storage backend. @@ -2046,7 +2057,7 @@ Set-up, restrictions and requirements: #. No additional settings or configuration is required to support this functionality. -#. Manage/Unmanage snapshots requires SnapVX functionality support on VMAX. +#. Manage/Unmanage snapshots requires SnapVX functionality support on PowerMax. #. Manage/Unmanage Snapshots in OpenStack Cinder is only supported at present through Cinder CLI commands. @@ -2056,7 +2067,7 @@ Set-up, restrictions and requirements: Manage SnapVX Snapshot ~~~~~~~~~~~~~~~~~~~~~~ -It is possible to manage VMAX SnapVX snapshots into OpenStack, where the +It is possible to manage PowerMax SnapVX snapshots into OpenStack, where the source volume from which the snapshot is taken already exists in, and is managed by OpenStack Cinder. The source volume may have been created in OpenStack Cinder, or it may have been managed in to OpenStack Cinder also. @@ -2083,7 +2094,7 @@ Requirements/Restrictions: Command Structure: -#. Identify your SnapVX snapshot for management on the VMAX, note the name. +#. Identify your SnapVX snapshot for management on the PowerMax, note the name. #. Ensure the source volume is already managed into OpenStack Cinder, note the device ID. @@ -2104,7 +2115,7 @@ Positional arguments: - - Source OpenStack volume name -- - Name of existing snapshot on VMAX backend +- - Name of existing snapshot on PowerMax backend Optional arguments: @@ -2121,7 +2132,7 @@ Example: $ cinder snapshot-manage --name SnapshotManaged \ --description "Managed Queens Feb18" \ - 0021A VMAXSnapshot + 0021A PowerMaxSnapshot Where: @@ -2132,13 +2143,14 @@ Where: - The source volume device ID is ``0021A``. -- The name of the SnapVX snapshot on the VMAX backend is ``VMAXSnapshot``. +- The name of the SnapVX snapshot on the PowerMax backend is + ``PowerMaxSnapshot``. Outcome: After the process of managing the Snapshot has completed, the SnapVX snapshot -on the VMAX backend will be prefixed by the letters ``OS-``, leaving the -snapshot in this example named ``OS-VMAXSnapshot``. The associated snapshot +on the PowerMax backend will be prefixed by the letters ``OS-``, leaving the +snapshot in this example named ``OS-PowerMaxSnapshot``. The associated snapshot managed by Cinder will be present for use under the name ``SnapshotManaged``. @@ -2148,8 +2160,8 @@ Unmanage Cinder Snapshot Unmanaging a snapshot in Cinder is the process whereby the snapshot is removed from and no longer managed by Cinder, but it still exists on the storage backend. Unmanaging a SnapVX snapshot in OpenStack Cinder follows this -behaviour, whereby after unmanaging a VMAX SnapVX snapshot from Cinder, the -snapshot is removed from OpenStack but is still present for use on the VMAX +behaviour, whereby after unmanaging a PowerMax SnapVX snapshot from Cinder, the +snapshot is removed from OpenStack but is still present for use on the PowerMax backend. Requirements/Restrictions: @@ -2181,9 +2193,9 @@ Where: - The SnapVX snapshot name in OpenStack Cinder is SnapshotManaged. After the process of unmanaging the SnapVX snapshot in Cinder, the snapshot on -the VMAX backend will have the ``OS-`` prefix removed to indicate it is no +the PowerMax backend will have the ``OS-`` prefix removed to indicate it is no longer OpenStack managed. In the example above, the snapshot after unmanaging -from OpenStack will be named ``VMAXSnapshot`` on the storage backend. +from OpenStack will be named ``PowerMaxSnapshot`` on the storage backend. List manageable volumes and snapshots ------------------------------------- @@ -2195,7 +2207,7 @@ Volumes that can be managed by and imported into Openstack. List manageable volume is filtered by: -- Volume size should be 1026MB or greater (1GB VMAX Cinder Vol = 1026 MB) +- Volume size should be 1026MB or greater (1GB PowerMax Cinder Vol = 1026 MB) - Volume size should be a whole integer GB capacity - Volume should not be a part of masking view. - Volume status should be ``Ready`` diff --git a/doc/source/configuration/block-storage/volume-drivers.rst b/doc/source/configuration/block-storage/volume-drivers.rst index bf80fc3413c..b1248800d73 100644 --- a/doc/source/configuration/block-storage/volume-drivers.rst +++ b/doc/source/configuration/block-storage/volume-drivers.rst @@ -37,7 +37,7 @@ Driver Configuration Reference drivers/dell-storagecenter-driver drivers/dell-emc-unity-driver drivers/dell-emc-vnx-driver - drivers/dell-emc-vmax-driver + drivers/dell-emc-powermax-driver drivers/dell-emc-vxflex-driver drivers/dell-emc-xtremio-driver drivers/drbd-driver diff --git a/releasenotes/notes/vmax-powermax-rebrand-70569fc8cdf40a8c.yaml b/releasenotes/notes/vmax-powermax-rebrand-70569fc8cdf40a8c.yaml new file mode 100644 index 00000000000..13360a19f59 --- /dev/null +++ b/releasenotes/notes/vmax-powermax-rebrand-70569fc8cdf40a8c.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + PowerMax driver - 'PowerMax' is to replace 'VMAX' in release notes, + online documentation, directory structure and driver name.