From 594a1a6687f514885744384ca147411433186fa1 Mon Sep 17 00:00:00 2001 From: Sonia Ghanekar Date: Wed, 30 Sep 2015 10:02:30 -0700 Subject: [PATCH] Add multi-initiator extra-spec for Nimble driver This patch allows setting up multi-initiator access for the Nimble driver through the extra-specs. This can be set by adding the key 'nimble:multi-initiator' with boolean value of 'true' or 'false'. If nothing is specified it defaults to 'false'. Change-Id: Iade49f0ce418a2db7ea9a00ebf925a017e3eb429 Closes-Bug: #1495750 --- cinder/tests/unit/test_nimble.py | 62 ++++++++++++++++++++++++++++---- cinder/volume/drivers/nimble.py | 24 ++++++++++--- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/cinder/tests/unit/test_nimble.py b/cinder/tests/unit/test_nimble.py index ceda31bba..8a21c31a6 100644 --- a/cinder/tests/unit/test_nimble.py +++ b/cinder/tests/unit/test_nimble.py @@ -282,7 +282,8 @@ class NimbleDriverVolumeTestCase(NimbleDriverBaseTestCase): 'online': True, 'pool-name': 'default', 'size': 1073741824, 'quota': 1073741824, 'perfpol-name': 'default', 'description': '', - 'agent-type': 5, 'encryptionAttr': {'cipher': 3}}, + 'agent-type': 5, 'encryptionAttr': {'cipher': 3}, + 'multi-initiator': 'false'}, 'sid': 'a9b9aba7'}) @mock.patch(NIMBLE_URLLIB2) @@ -291,8 +292,9 @@ class NimbleDriverVolumeTestCase(NimbleDriverBaseTestCase): mock.Mock(return_value=[])) @mock.patch.object(volume_types, 'get_volume_type_extra_specs', mock.Mock(type_id=FAKE_TYPE_ID, return_value={ - 'nimble:perfpol-name': 'default', - 'nimble:encryption': 'yes'})) + 'nimble:perfpol-name': 'default', + 'nimble:encryption': 'yes', + 'nimble:multi-initiator': 'false'})) @NimbleDriverBaseTestCase.client_mock_decorator(create_configuration( 'nimble', 'nimble_pass', '10.18.108.55', 'default', '*')) def test_create_volume_encryption_positive(self): @@ -323,7 +325,8 @@ class NimbleDriverVolumeTestCase(NimbleDriverBaseTestCase): 'online': True, 'pool-name': 'default', 'size': 1073741824, 'quota': 1073741824, 'perfpol-name': 'default', 'description': '', - 'agent-type': 5, 'encryptionAttr': {'cipher': 2}}, + 'agent-type': 5, 'encryptionAttr': {'cipher': 2}, + 'multi-initiator': 'false'}, 'sid': 'a9b9aba7'}) @mock.patch(NIMBLE_URLLIB2) @@ -332,8 +335,9 @@ class NimbleDriverVolumeTestCase(NimbleDriverBaseTestCase): mock.Mock(return_value=[])) @mock.patch.object(volume_types, 'get_volume_type_extra_specs', mock.Mock(type_id=FAKE_TYPE_ID, return_value={ - 'nimble:perfpol-name': 'VMware ESX', - 'nimble:encryption': 'no'})) + 'nimble:perfpol-name': 'VMware ESX', + 'nimble:encryption': 'no', + 'nimble:multi-initiator': 'false'})) @NimbleDriverBaseTestCase.client_mock_decorator(create_configuration( 'nimble', 'nimble_pass', '10.18.108.55', 'default', '*')) def test_create_volume_perfpolicy_positive(self): @@ -364,7 +368,51 @@ class NimbleDriverVolumeTestCase(NimbleDriverBaseTestCase): 'online': True, 'pool-name': 'default', 'size': 1073741824, 'quota': 1073741824, 'perfpol-name': 'VMware ESX', 'description': '', - 'agent-type': 5, 'encryptionAttr': {'cipher': 3}}, + 'agent-type': 5, 'encryptionAttr': {'cipher': 3}, + 'multi-initiator': 'false'}, + 'sid': 'a9b9aba7'}) + + @mock.patch(NIMBLE_URLLIB2) + @mock.patch(NIMBLE_CLIENT) + @mock.patch.object(obj_volume.VolumeList, 'get_all', + mock.Mock(return_value=[])) + @mock.patch.object(volume_types, 'get_volume_type_extra_specs', + mock.Mock(type_id=FAKE_TYPE_ID, return_value={ + 'nimble:perfpol-name': 'default', + 'nimble:encryption': 'no', + 'nimble:multi-initiator': 'true'})) + @NimbleDriverBaseTestCase.client_mock_decorator(create_configuration( + 'nimble', 'nimble_pass', '10.18.108.55', 'default', '*')) + def test_create_volume_multi_initiator_positive(self): + self.mock_client_service.service.createVol.return_value = \ + FAKE_CREATE_VOLUME_POSITIVE_RESPONSE_PERFPOLICY + self.mock_client_service.service.getVolInfo.return_value = \ + FAKE_GET_VOL_INFO_RESPONSE + self.mock_client_service.service.getNetConfig.return_value = \ + FAKE_POSITIVE_NETCONFIG_RESPONSE + + self.assertEqual( + {'provider_location': '172.18.108.21:3260 iqn.test 0', + 'provider_auth': None}, + self.driver.create_volume({'name': 'testvolume-perfpolicy', + 'size': 1, + 'volume_type_id': FAKE_TYPE_ID, + 'display_name': '', + 'display_description': ''})) + + mock_volume_type = volume_types.get_volume_type_extra_specs + mock_volume_type.assert_called_once_with(FAKE_TYPE_ID) + + self.mock_client_service.service.createVol.assert_called_once_with( + request={ + 'attr': {'snap-quota': sys.maxsize, + 'warn-level': 858993459, + 'name': 'testvolume-perfpolicy', 'reserve': 0, + 'online': True, 'pool-name': 'default', + 'size': 1073741824, 'quota': 1073741824, + 'perfpol-name': 'default', 'description': '', + 'agent-type': 5, 'encryptionAttr': {'cipher': 3}, + 'multi-initiator': 'true'}, 'sid': 'a9b9aba7'}) @mock.patch(NIMBLE_URLLIB2) diff --git a/cinder/volume/drivers/nimble.py b/cinder/volume/drivers/nimble.py index 50f9e8f20..883a471ad 100644 --- a/cinder/volume/drivers/nimble.py +++ b/cinder/volume/drivers/nimble.py @@ -43,8 +43,10 @@ AES_256_XTS_CIPHER = 2 DEFAULT_CIPHER = 3 EXTRA_SPEC_ENCRYPTION = 'nimble:encryption' EXTRA_SPEC_PERF_POLICY = 'nimble:perfpol-name' +EXTRA_SPEC_MULTI_INITIATOR = 'nimble:multi-initiator' DEFAULT_PERF_POLICY_SETTING = 'default' DEFAULT_ENCRYPTION_SETTING = 'no' +DEFAULT_MULTI_INITIATOR_SETTING = 'false' DEFAULT_SNAP_QUOTA = sys.maxsize VOL_EDIT_MASK = 4 + 16 + 32 + 64 + 256 + 512 MANAGE_EDIT_MASK = 1 + 262144 @@ -617,8 +619,14 @@ class NimbleAPIExecutor(object): DEFAULT_PERF_POLICY_SETTING) encryption = extra_specs.get(EXTRA_SPEC_ENCRYPTION, DEFAULT_ENCRYPTION_SETTING) + multi_initiator = extra_specs.get(EXTRA_SPEC_MULTI_INITIATOR, + DEFAULT_MULTI_INITIATOR_SETTING) + extra_specs_map = {} + extra_specs_map[EXTRA_SPEC_PERF_POLICY] = perf_policy_name + extra_specs_map[EXTRA_SPEC_ENCRYPTION] = encryption + extra_specs_map[EXTRA_SPEC_MULTI_INITIATOR] = multi_initiator - return perf_policy_name, encryption + return extra_specs_map @_connection_checker @_response_checker @@ -634,7 +642,10 @@ class NimbleAPIExecutor(object): description = description[:254] specs = self._get_volumetype_extraspecs(volume) - perf_policy_name, encrypt = self._get_extra_spec_values(specs) + extra_specs_map = self._get_extra_spec_values(specs) + perf_policy_name = extra_specs_map[EXTRA_SPEC_PERF_POLICY] + encrypt = extra_specs_map[EXTRA_SPEC_ENCRYPTION] + multi_initiator = extra_specs_map[EXTRA_SPEC_MULTI_INITIATOR] # default value of cipher for encryption cipher = DEFAULT_CIPHER if encrypt.lower() == 'yes': @@ -645,7 +656,8 @@ class NimbleAPIExecutor(object): ' description=%(description)s with Extra Specs' ' perfpol-name=%(perfpol-name)s' ' encryption=%(encryption)s cipher=%(cipher)s' - ' agent-type=%(agent-type)s', + ' agent-type=%(agent-type)s' + ' multi-initiator=%(multi-initiator)s', {'vol': volume['name'], 'size': volume_size, 'reserve': reserve, @@ -654,7 +666,8 @@ class NimbleAPIExecutor(object): 'perfpol-name': perf_policy_name, 'encryption': encrypt, 'cipher': cipher, - 'agent-type': AGENT_TYPE_OPENSTACK}) + 'agent-type': AGENT_TYPE_OPENSTACK, + 'multi-initiator': multi_initiator}) return self.client.service.createVol( request={'sid': self.sid, @@ -669,7 +682,8 @@ class NimbleAPIExecutor(object): 'pool-name': pool_name, 'agent-type': AGENT_TYPE_OPENSTACK, 'perfpol-name': perf_policy_name, - 'encryptionAttr': {'cipher': cipher}}}) + 'encryptionAttr': {'cipher': cipher}, + 'multi-initiator': multi_initiator}}) def create_vol(self, volume, pool_name, reserve): """Execute createVol API.""" -- 2.45.2