Merge "3PAR FC: add ability to add WWNs to host"
This commit is contained in:
commit
57a7422c2e
|
@ -18,6 +18,7 @@
|
|||
Unit tests for OpenStack Cinder volume drivers
|
||||
"""
|
||||
import ast
|
||||
import mock
|
||||
import mox
|
||||
import shutil
|
||||
import tempfile
|
||||
|
@ -786,7 +787,10 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||
'123456789054321'])
|
||||
_run_ssh(create_host_cmd, False).AndReturn([CLI_CR, ''])
|
||||
|
||||
getHost('fakehost').AndReturn({'name': self.FAKE_HOST})
|
||||
getHost('fakehost').AndReturn({'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'wwn': '123456789012345'},
|
||||
{'wwn': '123456789054321'}]}
|
||||
)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
host = self.driver._create_host(self.volume, self.connector)
|
||||
|
@ -817,7 +821,12 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||
'already used by host fakehost.foo (19)')
|
||||
_run_ssh(create_host_cmd, False).AndReturn([create_host_ret, ''])
|
||||
|
||||
getHost('fakehost.foo').AndReturn({'name': 'fakehost.foo'})
|
||||
host_ret = {
|
||||
'name': 'fakehost.foo',
|
||||
'FCPaths': [{'wwn': '123456789012345'},
|
||||
{'wwn': '123456789054321'}]}
|
||||
getHost('fakehost.foo').AndReturn(host_ret)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
host = self.driver._create_host(self.volume, self.connector)
|
||||
|
@ -848,8 +857,8 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||
'pathOperation': 1})
|
||||
|
||||
getHost('fakehost').AndReturn({'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'WWN': '123456789012345'},
|
||||
{'WWN': '123456789054321'}]}
|
||||
'FCPaths': [{'wwn': '123456789012345'},
|
||||
{'wwn': '123456789054321'}]}
|
||||
)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
@ -858,6 +867,82 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
|
|||
self.assertEqual(host['name'], self.FAKE_HOST)
|
||||
self.assertEqual(len(host['FCPaths']), 2)
|
||||
|
||||
def test_modify_host_with_new_wwn(self):
|
||||
self.flags(lock_path=self.tempdir)
|
||||
self.clear_mox()
|
||||
|
||||
hpdriver.hpcommon.HP3PARCommon.get_cpg = mock.Mock(
|
||||
return_value=self.fake_get_cpg)
|
||||
hpdriver.hpcommon.HP3PARCommon.get_domain = mock.Mock(
|
||||
return_value=self.fake_get_domain)
|
||||
|
||||
# set up the getHost mock
|
||||
self.driver.common.client.getHost = mock.Mock()
|
||||
# define the return values for the 2 calls
|
||||
getHost_ret1 = {
|
||||
'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'wwn': '123456789054321'}]}
|
||||
getHost_ret2 = {
|
||||
'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'wwn': '123456789012345'},
|
||||
{'wwn': '123456789054321'}]}
|
||||
self.driver.common.client.getHost.side_effect = [
|
||||
getHost_ret1, getHost_ret2]
|
||||
|
||||
# setup the modifyHost mock
|
||||
self.driver.common.client.modifyHost = mock.Mock()
|
||||
|
||||
host = self.driver._create_host(self.volume, self.connector)
|
||||
|
||||
# mock assertions
|
||||
self.driver.common.client.getHost.assert_has_calls([
|
||||
mock.call('fakehost'),
|
||||
mock.call('fakehost')])
|
||||
self.driver.common.client.modifyHost.assert_called_once_with(
|
||||
'fakehost', {'FCWWNs': ['123456789012345'], 'pathOperation': 1})
|
||||
|
||||
self.assertEqual(host['name'], self.FAKE_HOST)
|
||||
self.assertEqual(len(host['FCPaths']), 2)
|
||||
|
||||
def test_modify_host_with_unknown_wwn_and_new_wwn(self):
|
||||
self.flags(lock_path=self.tempdir)
|
||||
self.clear_mox()
|
||||
|
||||
hpdriver.hpcommon.HP3PARCommon.get_cpg = mock.Mock(
|
||||
return_value=self.fake_get_cpg)
|
||||
hpdriver.hpcommon.HP3PARCommon.get_domain = mock.Mock(
|
||||
return_value=self.fake_get_domain)
|
||||
|
||||
# set up the getHost mock
|
||||
self.driver.common.client.getHost = mock.Mock()
|
||||
# define the return values for the 2 calls
|
||||
getHost_ret1 = {
|
||||
'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'wwn': '123456789054321'},
|
||||
{'wwn': 'xxxxxxxxxxxxxxx'}]}
|
||||
getHost_ret2 = {
|
||||
'name': self.FAKE_HOST,
|
||||
'FCPaths': [{'wwn': '123456789012345'},
|
||||
{'wwn': '123456789054321'},
|
||||
{'wwn': 'xxxxxxxxxxxxxxx'}]}
|
||||
self.driver.common.client.getHost.side_effect = [
|
||||
getHost_ret1, getHost_ret2]
|
||||
|
||||
# setup the modifyHost mock
|
||||
self.driver.common.client.modifyHost = mock.Mock()
|
||||
|
||||
host = self.driver._create_host(self.volume, self.connector)
|
||||
|
||||
# mock assertions
|
||||
self.driver.common.client.getHost.assert_has_calls([
|
||||
mock.call('fakehost'),
|
||||
mock.call('fakehost')])
|
||||
self.driver.common.client.modifyHost.assert_called_once_with(
|
||||
'fakehost', {'FCWWNs': ['123456789012345'], 'pathOperation': 1})
|
||||
|
||||
self.assertEqual(host['name'], self.FAKE_HOST)
|
||||
self.assertEqual(len(host['FCPaths']), 3)
|
||||
|
||||
|
||||
class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
|
||||
|
||||
|
|
|
@ -56,9 +56,10 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
|
|||
the drivers to use the new APIs.
|
||||
1.2.1 - Synchronized extend_volume method.
|
||||
1.2.2 - Added try/finally around client login/logout.
|
||||
1.2.3 - Added ability to add WWNs to host.
|
||||
"""
|
||||
|
||||
VERSION = "1.2.2"
|
||||
VERSION = "1.2.3"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(HP3PARFCDriver, self).__init__(*args, **kwargs)
|
||||
|
@ -261,9 +262,6 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
|
|||
domain = self.common.get_domain(cpg)
|
||||
try:
|
||||
host = self.common._get_3par_host(hostname)
|
||||
if 'FCPaths' not in host or len(host['FCPaths']) < 1:
|
||||
self._modify_3par_fibrechan_host(hostname, connector['wwpns'])
|
||||
host = self.common._get_3par_host(hostname)
|
||||
except hpexceptions.HTTPNotFound as ex:
|
||||
# get persona from the volume type extra specs
|
||||
persona_id = self.common.get_persona_type(volume)
|
||||
|
@ -274,6 +272,35 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
|
|||
persona_id)
|
||||
host = self.common._get_3par_host(hostname)
|
||||
|
||||
return self._add_new_wwn_to_host(host, connector['wwpns'])
|
||||
|
||||
def _add_new_wwn_to_host(self, host, wwns):
|
||||
"""Add wwns to a host if one or more don't exist.
|
||||
|
||||
Identify if argument wwns contains any world wide names
|
||||
not configured in the 3PAR host path. If any are found,
|
||||
add them to the 3PAR host.
|
||||
"""
|
||||
# get the currently configured wwns
|
||||
# from the host's FC paths
|
||||
host_wwns = []
|
||||
if 'FCPaths' in host:
|
||||
for path in host['FCPaths']:
|
||||
wwn = path.get('wwn', None)
|
||||
if wwn is not None:
|
||||
host_wwns.append(wwn.lower())
|
||||
|
||||
# lower case all wwns in the compare list
|
||||
compare_wwns = [x.lower() for x in wwns]
|
||||
|
||||
# calculate wwns in compare list, but not in host_wwns list
|
||||
new_wwns = list(set(compare_wwns).difference(host_wwns))
|
||||
|
||||
# if any wwns found that were not in host list,
|
||||
# add them to the host
|
||||
if (len(new_wwns) > 0):
|
||||
self._modify_3par_fibrechan_host(host['name'], new_wwns)
|
||||
host = self.common._get_3par_host(host['name'])
|
||||
return host
|
||||
|
||||
@utils.synchronized('3par', external=True)
|
||||
|
|
Loading…
Reference in New Issue