From cbc67e012ad5f9234ea34a37e6240d608508da86 Mon Sep 17 00:00:00 2001 From: Anthony Lee Date: Thu, 2 Apr 2015 22:07:27 -0700 Subject: [PATCH] Fixed encrypted property for 3PAR FC and iSCSI drivers 3PAR FC and iSCSI drivers were not returning the 'encrypted' property when initialize_connection was called. This patch adds that property to the returned info. Closes-Bug: #1439917 Change-Id: Icfbebd055ea1bae1fc4749b441eb4f90fa1bfacd --- cinder/tests/test_hp3par.py | 143 +++++++++++++++++- cinder/volume/drivers/san/hp/hp_3par_fc.py | 9 +- cinder/volume/drivers/san/hp/hp_3par_iscsi.py | 7 +- 3 files changed, 156 insertions(+), 3 deletions(-) diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index a11d96814..cc3fb0097 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -123,6 +123,15 @@ class HP3PARBaseDriver(object): 'volume_type': None, 'volume_type_id': None} + volume_encrypted = {'name': VOLUME_NAME, + 'id': VOLUME_ID, + 'display_name': 'Foo Volume', + 'size': 2, + 'host': FAKE_CINDER_HOST, + 'volume_type': None, + 'volume_type_id': None, + 'encryption_key_id': 'fake_key'} + volume_dedup = {'name': VOLUME_NAME, 'id': VOLUME_ID, 'display_name': 'Foo Volume', @@ -2923,6 +2932,7 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): properties = { 'driver_volume_type': 'fibre_channel', 'data': { + 'encrypted': False, 'target_lun': 90, 'target_wwn': ['0987654321234', '123456789000987'], 'target_discovered': True, @@ -3079,6 +3089,7 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): expected_properties = { 'driver_volume_type': 'fibre_channel', 'data': { + 'encrypted': False, 'target_lun': 90, 'target_wwn': ['0987654321234'], 'target_discovered': True, @@ -3113,6 +3124,77 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase): self.assertDictMatch(result, expected_properties) + def test_initialize_connection_encrypted(self): + # setup_mock_client drive with default configuration + # and return the mock HTTP 3PAR client + mock_client = self.setup_driver() + mock_client.getVolume.return_value = {'userCPG': HP3PAR_CPG} + mock_client.getCPG.return_value = {} + mock_client.getHost.side_effect = [ + hpexceptions.HTTPNotFound('fake'), + {'name': self.FAKE_HOST, + 'FCPaths': [{'driverVersion': None, + 'firmwareVersion': None, + 'hostSpeed': 0, + 'model': None, + 'portPos': {'cardPort': 1, 'node': 1, + 'slot': 2}, + 'vendor': None, + 'wwn': self.wwn[0]}, + {'driverVersion': None, + 'firmwareVersion': None, + 'hostSpeed': 0, + 'model': None, + 'portPos': {'cardPort': 1, 'node': 0, + 'slot': 2}, + 'vendor': None, + 'wwn': self.wwn[1]}]}] + mock_client.queryHost.return_value = { + 'members': [{ + 'name': self.FAKE_HOST + }] + } + mock_client.getHostVLUNs.return_value = [ + {'active': True, + 'volumeName': self.VOLUME_3PAR_NAME, + 'lun': 90, 'type': 0}] + location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" % + {'volume_name': self.VOLUME_3PAR_NAME, + 'lun_id': 90, + 'host': self.FAKE_HOST, + 'nsp': 'something'}) + mock_client.createVLUN.return_value = location + + with mock.patch.object(hpcommon.HP3PARCommon, + '_create_client') as mock_create_client: + mock_create_client.return_value = mock_client + result = self.driver.initialize_connection( + self.volume_encrypted, + self.connector) + + expected = [ + mock.call.getVolume(self.VOLUME_3PAR_NAME), + mock.call.getCPG(HP3PAR_CPG), + mock.call.getHost(self.FAKE_HOST), + mock.call.queryHost(wwns=['123456789012345', + '123456789054321']), + mock.call.getHost(self.FAKE_HOST), + mock.call.getPorts(), + mock.call.createVLUN( + self.VOLUME_3PAR_NAME, + auto=True, + hostname=self.FAKE_HOST), + mock.call.getHostVLUNs(self.FAKE_HOST)] + + mock_client.assert_has_calls( + self.standard_login + + expected + + self.standard_logout) + + expected_properties = self.properties + expected_properties['data']['encrypted'] = True + self.assertDictMatch(result, expected_properties) + def test_terminate_connection(self): # setup_mock_client drive with default configuration # and return the mock HTTP 3PAR client @@ -3601,7 +3683,8 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase): properties = { 'driver_volume_type': 'iscsi', 'data': - {'target_discovered': True, + {'encrypted': False, + 'target_discovered': True, 'target_iqn': TARGET_IQN, 'target_lun': TARGET_LUN, 'target_portal': '1.1.1.2:1234'}} @@ -3693,6 +3776,64 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase): self.assertDictMatch(result, self.properties) + def test_initialize_connection_encrypted(self): + # setup_mock_client drive with default configuration + # and return the mock HTTP 3PAR client + mock_client = self.setup_driver() + mock_client.getVolume.return_value = {'userCPG': HP3PAR_CPG} + mock_client.getCPG.return_value = {} + mock_client.getHost.side_effect = [ + hpexceptions.HTTPNotFound('fake'), + {'name': self.FAKE_HOST}] + mock_client.queryHost.return_value = { + 'members': [{ + 'name': self.FAKE_HOST + }] + } + mock_client.getHostVLUNs.return_value = [ + {'active': True, + 'volumeName': self.VOLUME_3PAR_NAME, + 'lun': self.TARGET_LUN, 'type': 0}] + mock_client.getVLUN.return_value = { + 'lun': self.TARGET_LUN, + 'portPos': {'node': 8, 'slot': 1, 'cardPort': 1}} + location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" % + {'volume_name': self.VOLUME_3PAR_NAME, + 'lun_id': self.TARGET_LUN, + 'host': self.FAKE_HOST, + 'nsp': 'something'}) + mock_client.createVLUN.return_value = location + + with mock.patch.object(hpcommon.HP3PARCommon, + '_create_client') as mock_create_client: + mock_create_client.return_value = mock_client + result = self.driver.initialize_connection( + self.volume_encrypted, + self.connector) + + expected = [ + mock.call.getVolume(self.VOLUME_3PAR_NAME), + mock.call.getCPG(HP3PAR_CPG), + mock.call.getHost(self.FAKE_HOST), + mock.call.queryHost(iqns=['iqn.1993-08.org.debian:01:222']), + mock.call.getHost(self.FAKE_HOST), + mock.call.getVLUN(self.VOLUME_3PAR_NAME), + mock.call.createVLUN( + self.VOLUME_3PAR_NAME, + auto=True, + hostname='fakehost', + portPos={'node': 8, 'slot': 1, 'cardPort': 1}), + mock.call.getHostVLUNs(self.FAKE_HOST)] + + mock_client.assert_has_calls( + self.standard_login + + expected + + self.standard_logout) + + expected_properties = self.properties + expected_properties['data']['encrypted'] = True + self.assertDictMatch(result, self.properties) + def test_get_volume_stats(self): # setup_mock_client drive with the configuration # and return the mock HTTP 3PAR client diff --git a/cinder/volume/drivers/san/hp/hp_3par_fc.py b/cinder/volume/drivers/san/hp/hp_3par_fc.py index afebdbf8f..78420b123 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_fc.py +++ b/cinder/volume/drivers/san/hp/hp_3par_fc.py @@ -77,10 +77,11 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): 2.0.13 - Fix missing host name during attach bug #1398206 2.0.14 - Removed usage of host name cache #1398914 2.0.15 - Added support for updated detach_volume attachment. + 2.0.16 - Added encrypted property to initialize_connection #1439917 """ - VERSION = "2.0.15" + VERSION = "2.0.16" def __init__(self, *args, **kwargs): super(HP3PARFCDriver, self).__init__(*args, **kwargs) @@ -194,6 +195,7 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): { 'driver_volume_type': 'fibre_channel' 'data': { + 'encrypted': False, 'target_discovered': True, 'target_lun': 1, 'target_wwn': '1234567890123', @@ -205,6 +207,7 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): { 'driver_volume_type': 'fibre_channel' 'data': { + 'encrypted': False, 'target_discovered': True, 'target_lun': 1, 'target_wwn': ['1234567890123', '0987654321321'], @@ -242,6 +245,10 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver): 'target_discovered': True, 'target_wwn': target_wwns, 'initiator_target_map': init_targ_map}} + + encryption_key_id = volume.get('encryption_key_id', None) + info['data']['encrypted'] = encryption_key_id is not None + return info finally: self._logout(common) diff --git a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py index 8eea79afa..8f55465ea 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py +++ b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py @@ -84,10 +84,11 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver): 2.0.14 - Do not allow a different iSCSI IP (hp3par_iscsi_ips) to be used during live-migration. bug #1423958 2.0.15 - Added support for updated detach_volume attachment. + 2.0.16 - Added encrypted property to initialize_connection #1439917 """ - VERSION = "2.0.15" + VERSION = "2.0.16" def __init__(self, *args, **kwargs): super(HP3PARISCSIDriver, self).__init__(*args, **kwargs) @@ -266,6 +267,7 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver): { 'driver_volume_type': 'iscsi' 'data': { + 'encrypted': False, 'target_discovered': True, 'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001', 'target_protal': '127.0.0.1:3260', @@ -333,6 +335,9 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver): info['data']['auth_username'] = username info['data']['auth_password'] = password + encryption_key_id = volume.get('encryption_key_id', None) + info['data']['encrypted'] = encryption_key_id is not None + return info finally: self._logout(common) -- 2.45.2