NetApp E-Series: Refactor class structure for FC
This patch moves classes to mimic the NetApp ONTAP drivers class structure by creating a library module, making the iSCSI driver a thin layer. This way the E-Series FC driver can be added in a similar manner. Change-Id: I8b4ed6a7b2d43cd93da5c340646405e3041a312a
This commit is contained in:
parent
2448e04159
commit
b4740677cc
|
@ -32,7 +32,7 @@ from cinder import test
|
|||
from cinder.volume import configuration as conf
|
||||
from cinder.volume.drivers.netapp import common
|
||||
from cinder.volume.drivers.netapp.eseries import client
|
||||
from cinder.volume.drivers.netapp.eseries import iscsi
|
||||
from cinder.volume.drivers.netapp.eseries import library
|
||||
from cinder.volume.drivers.netapp.eseries import utils
|
||||
from cinder.volume.drivers.netapp import options
|
||||
import cinder.volume.drivers.netapp.utils as na_utils
|
||||
|
@ -671,6 +671,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
self.mock_object(na_utils, 'OpenStackInfo')
|
||||
configuration = self._set_config(create_configuration())
|
||||
self.driver = common.NetAppDriver(configuration=configuration)
|
||||
self.library = self.driver.library
|
||||
self.mock_object(requests, 'Session', FakeEseriesHTTPSession)
|
||||
self.driver.do_setup(context='context')
|
||||
self.driver.check_for_setup_error()
|
||||
|
@ -695,7 +696,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration.netapp_controller_ips = '127.0.0.1,127.0.0.3'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver.do_setup(context='context')
|
||||
self.assertEqual(driver._client.get_system_id(),
|
||||
self.assertEqual(driver.library._client.get_system_id(),
|
||||
'1fa6efb5-f07b-4de4-9f0e-52e5f7ff5d1b')
|
||||
|
||||
def test_check_system_pwd_not_sync(self):
|
||||
|
@ -705,8 +706,8 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
return {'status': 'passwordoutofsync'}
|
||||
return {'status': 'needsAttention'}
|
||||
|
||||
self.driver._client.list_storage_system = mock.Mock(wraps=list_system)
|
||||
result = self.driver._check_storage_system()
|
||||
self.library._client.list_storage_system = mock.Mock(wraps=list_system)
|
||||
result = self.library._check_storage_system()
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_connect(self):
|
||||
|
@ -720,10 +721,10 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
self.driver.get_volume_stats(refresh=False)
|
||||
|
||||
def test_get_pool(self):
|
||||
self.mock_object(self.driver, '_get_volume',
|
||||
self.mock_object(self.library, '_get_volume',
|
||||
mock.Mock(return_value={
|
||||
'volumeGroupRef': 'fake_ref'}))
|
||||
self.mock_object(self.driver._client, "get_storage_pool",
|
||||
self.mock_object(self.library._client, "get_storage_pool",
|
||||
mock.Mock(return_value={'volumeGroupRef': 'fake_ref',
|
||||
'label': 'ddp1'}))
|
||||
|
||||
|
@ -732,21 +733,23 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
self.assertEqual(pool, 'ddp1')
|
||||
|
||||
def test_get_pool_no_pools(self):
|
||||
self.mock_object(self.driver, '_get_volume',
|
||||
self.mock_object(self.library, '_get_volume',
|
||||
mock.Mock(return_value={
|
||||
'volumeGroupRef': 'fake_ref'}))
|
||||
self.mock_object(self.driver._client, "get_storage_pool",
|
||||
self.mock_object(self.library._client, "get_storage_pool",
|
||||
mock.Mock(return_value=None))
|
||||
|
||||
pool = self.driver.get_pool({'name_id': 'fake-uuid'})
|
||||
|
||||
self.assertEqual(pool, None)
|
||||
|
||||
@mock.patch.object(iscsi.NetAppEseriesISCSIDriver, '_create_volume',
|
||||
@mock.patch.object(library.NetAppESeriesLibrary, '_create_volume',
|
||||
mock.Mock())
|
||||
def test_create_volume(self):
|
||||
|
||||
self.driver.create_volume(self.volume)
|
||||
self.driver._create_volume.assert_called_with(
|
||||
|
||||
self.library._create_volume.assert_called_with(
|
||||
'DDP', self.fake_eseries_volume_label, self.volume['size'])
|
||||
|
||||
def test_create_volume_no_pool_provided_by_scheduler(self):
|
||||
|
@ -765,10 +768,12 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
fake_list_pools.return_value = fake_pools
|
||||
wrong_eseries_pool_label = 'hostname@backend'
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver._create_volume, wrong_eseries_pool_label,
|
||||
self.fake_eseries_volume_label, self.fake_size_gb)
|
||||
self.library._create_volume,
|
||||
wrong_eseries_pool_label,
|
||||
self.fake_eseries_volume_label,
|
||||
self.fake_size_gb)
|
||||
|
||||
@mock.patch.object(iscsi.LOG, 'info')
|
||||
@mock.patch.object(library.LOG, 'info')
|
||||
@mock.patch.object(client.RestClient, 'list_storage_pools')
|
||||
@mock.patch.object(client.RestClient, 'create_volume',
|
||||
mock.MagicMock(return_value='CorrectVolume'))
|
||||
|
@ -779,7 +784,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
fake_pool['raidLevel'] = 'raidDiskPool'
|
||||
fake_pools = [fake_pool]
|
||||
storage_pools.return_value = fake_pools
|
||||
storage_vol = self.driver._create_volume(
|
||||
storage_vol = self.library._create_volume(
|
||||
self.fake_eseries_pool_label,
|
||||
self.fake_eseries_volume_label,
|
||||
self.fake_size_gb)
|
||||
|
@ -791,7 +796,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
@mock.patch.object(client.RestClient, 'create_volume',
|
||||
mock.MagicMock(
|
||||
side_effect=exception.NetAppDriverException))
|
||||
@mock.patch.object(iscsi.LOG, 'info', mock.Mock())
|
||||
@mock.patch.object(library.LOG, 'info', mock.Mock())
|
||||
def test_create_volume_check_exception(self, fake_list_pools):
|
||||
fake_pool = {}
|
||||
fake_pool['label'] = self.fake_eseries_pool_label
|
||||
|
@ -800,7 +805,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
fake_pools = [fake_pool]
|
||||
fake_list_pools.return_value = fake_pools
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver._create_volume,
|
||||
self.library._create_volume,
|
||||
self.fake_eseries_pool_label,
|
||||
self.fake_eseries_volume_label, self.fake_size_gb)
|
||||
|
||||
|
@ -809,9 +814,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
vol_nomatch = {'id': 'vol_id', 'currentManager': 'ctrl3'}
|
||||
portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
|
||||
{'controller': 'ctrl1', 'iqn': 'iqn1'}]
|
||||
portal = self.driver._get_iscsi_portal_for_vol(volume, portals)
|
||||
portal = self.library._get_iscsi_portal_for_vol(volume, portals)
|
||||
self.assertEqual(portal, {'controller': 'ctrl1', 'iqn': 'iqn1'})
|
||||
portal = self.driver._get_iscsi_portal_for_vol(vol_nomatch, portals)
|
||||
portal = self.library._get_iscsi_portal_for_vol(vol_nomatch, portals)
|
||||
self.assertEqual(portal, {'controller': 'ctrl2', 'iqn': 'iqn2'})
|
||||
|
||||
def test_portal_for_vol_any_false(self):
|
||||
|
@ -819,7 +824,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
|
||||
{'controller': 'ctrl1', 'iqn': 'iqn1'}]
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver._get_iscsi_portal_for_vol,
|
||||
self.library._get_iscsi_portal_for_vol,
|
||||
vol_nomatch, portals, False)
|
||||
|
||||
def test_setup_error_unsupported_host_type(self):
|
||||
|
@ -827,20 +832,20 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration.netapp_host_type = 'garbage'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
driver.check_for_setup_error)
|
||||
driver.library.check_for_setup_error)
|
||||
|
||||
def test_check_host_type_default(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_host_type()
|
||||
self.assertEqual('LnxALUA', driver.host_type)
|
||||
driver.library._check_host_type()
|
||||
self.assertEqual('LnxALUA', driver.library.host_type)
|
||||
|
||||
def test_do_setup_all_default(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.library._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.do_setup(context='context')
|
||||
url = urllib.parse.urlparse(driver._client._endpoint)
|
||||
url = urllib.parse.urlparse(driver.library._client._endpoint)
|
||||
port = url.port
|
||||
scheme = url.scheme
|
||||
self.assertEqual(8080, port)
|
||||
|
@ -850,9 +855,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_transport_type = 'http'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.library._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.do_setup(context='context')
|
||||
url = urllib.parse.urlparse(driver._client._endpoint)
|
||||
url = urllib.parse.urlparse(driver.library._client._endpoint)
|
||||
port = url.port
|
||||
scheme = url.scheme
|
||||
self.assertEqual(8080, port)
|
||||
|
@ -862,9 +867,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_transport_type = 'https'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.library._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.do_setup(context='context')
|
||||
url = urllib.parse.urlparse(driver._client._endpoint)
|
||||
url = urllib.parse.urlparse(driver.library._client._endpoint)
|
||||
port = url.port
|
||||
scheme = url.scheme
|
||||
self.assertEqual(8443, port)
|
||||
|
@ -874,9 +879,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_server_port = 81
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.library._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.do_setup(context='context')
|
||||
url = urllib.parse.urlparse(driver._client._endpoint)
|
||||
url = urllib.parse.urlparse(driver.library._client._endpoint)
|
||||
port = url.port
|
||||
scheme = url.scheme
|
||||
self.assertEqual(81, port)
|
||||
|
@ -887,9 +892,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration.netapp_transport_type = 'https'
|
||||
configuration.netapp_server_port = 446
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.library._check_mode_get_or_register_storage_system = mock.Mock()
|
||||
driver.do_setup(context='context')
|
||||
url = urllib.parse.urlparse(driver._client._endpoint)
|
||||
url = urllib.parse.urlparse(driver.library._client._endpoint)
|
||||
port = url.port
|
||||
scheme = url.scheme
|
||||
self.assertEqual(446, port)
|
||||
|
@ -899,13 +904,13 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '127.0.0.1'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system
|
||||
driver.library._check_mode_get_or_register_storage_system
|
||||
|
||||
def test_setup_good_controller_ips(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '127.0.0.2,127.0.0.1'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
driver._check_mode_get_or_register_storage_system
|
||||
driver.library._check_mode_get_or_register_storage_system
|
||||
|
||||
def test_setup_missing_controller_ip(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
|
@ -918,33 +923,37 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '987.65.43.21'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
self.assertRaises(exception.NoValidHost,
|
||||
driver._check_mode_get_or_register_storage_system)
|
||||
self.assertRaises(
|
||||
exception.NoValidHost,
|
||||
driver.library._check_mode_get_or_register_storage_system)
|
||||
|
||||
def test_setup_error_invalid_first_controller_ip(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '987.65.43.21,127.0.0.1'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
self.assertRaises(exception.NoValidHost,
|
||||
driver._check_mode_get_or_register_storage_system)
|
||||
self.assertRaises(
|
||||
exception.NoValidHost,
|
||||
driver.library._check_mode_get_or_register_storage_system)
|
||||
|
||||
def test_setup_error_invalid_second_controller_ip(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '127.0.0.1,987.65.43.21'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
self.assertRaises(exception.NoValidHost,
|
||||
driver._check_mode_get_or_register_storage_system)
|
||||
self.assertRaises(
|
||||
exception.NoValidHost,
|
||||
driver.library._check_mode_get_or_register_storage_system)
|
||||
|
||||
def test_setup_error_invalid_both_controller_ips(self):
|
||||
configuration = self._set_config(create_configuration())
|
||||
configuration.netapp_controller_ips = '564.124.1231.1,987.65.43.21'
|
||||
driver = common.NetAppDriver(configuration=configuration)
|
||||
self.assertRaises(exception.NoValidHost,
|
||||
driver._check_mode_get_or_register_storage_system)
|
||||
self.assertRaises(
|
||||
exception.NoValidHost,
|
||||
driver.library._check_mode_get_or_register_storage_system)
|
||||
|
||||
def test_get_vol_with_label_wwn_missing(self):
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver._get_volume_with_label_wwn,
|
||||
self.library._get_volume_with_label_wwn,
|
||||
None, None)
|
||||
|
||||
def test_get_vol_with_label_wwn_found(self):
|
||||
|
@ -954,10 +963,11 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
{'volumeRef': '2', 'volumeUse': 'standardVolume',
|
||||
'label': 'l2', 'volumeGroupRef': 'g2',
|
||||
'worldWideName': 'w2ghyu'}]
|
||||
self.driver._get_storage_pools = mock.Mock(return_value=['g2', 'g3'])
|
||||
self.driver._client.list_volumes = mock.Mock(return_value=fake_vl_list)
|
||||
vol = self.driver._get_volume_with_label_wwn('l2', 'w2:gh:yu')
|
||||
self.assertEqual(1, self.driver._client.list_volumes.call_count)
|
||||
self.library._get_storage_pools = mock.Mock(return_value=['g2', 'g3'])
|
||||
self.library._client.list_volumes = mock.Mock(
|
||||
return_value=fake_vl_list)
|
||||
vol = self.library._get_volume_with_label_wwn('l2', 'w2:gh:yu')
|
||||
self.assertEqual(1, self.library._client.list_volumes.call_count)
|
||||
self.assertEqual('2', vol['volumeRef'])
|
||||
|
||||
def test_get_vol_with_label_wwn_unmatched(self):
|
||||
|
@ -967,23 +977,24 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
{'volumeRef': '2', 'volumeUse': 'standardVolume',
|
||||
'label': 'l2', 'volumeGroupRef': 'g2',
|
||||
'worldWideName': 'w2ghyu'}]
|
||||
self.driver._get_storage_pools = mock.Mock(return_value=['g2', 'g3'])
|
||||
self.driver._client.list_volumes = mock.Mock(return_value=fake_vl_list)
|
||||
self.assertRaises(KeyError, self.driver._get_volume_with_label_wwn,
|
||||
self.library._get_storage_pools = mock.Mock(return_value=['g2', 'g3'])
|
||||
self.library._client.list_volumes = mock.Mock(
|
||||
return_value=fake_vl_list)
|
||||
self.assertRaises(KeyError, self.library._get_volume_with_label_wwn,
|
||||
'l2', 'abcdef')
|
||||
self.assertEqual(1, self.driver._client.list_volumes.call_count)
|
||||
self.assertEqual(1, self.library._client.list_volumes.call_count)
|
||||
|
||||
def test_manage_existing_get_size(self):
|
||||
self.driver._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
self.library._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
return_value=self.fake_ret_vol)
|
||||
size = self.driver.manage_existing_get_size(self.volume, self.fake_ref)
|
||||
self.assertEqual(3, size)
|
||||
self.driver._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.library._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.volume, self.fake_ref)
|
||||
|
||||
def test_get_exist_vol_source_name_missing(self):
|
||||
self.assertRaises(exception.ManageExistingInvalidReference,
|
||||
self.driver._get_existing_vol_with_manage_ref,
|
||||
self.library._get_existing_vol_with_manage_ref,
|
||||
self.volume, {'id': '1234'})
|
||||
|
||||
def test_get_exist_vol_source_not_found(self):
|
||||
|
@ -991,53 +1002,53 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
d = {'id': '1'}
|
||||
return d[v_id]
|
||||
|
||||
self.driver._get_volume_with_label_wwn = mock.Mock(wraps=_get_volume)
|
||||
self.library._get_volume_with_label_wwn = mock.Mock(wraps=_get_volume)
|
||||
self.assertRaises(exception.ManageExistingInvalidReference,
|
||||
self.driver._get_existing_vol_with_manage_ref,
|
||||
self.library._get_existing_vol_with_manage_ref,
|
||||
{'id': 'id2'}, {'source-name': 'name2'})
|
||||
self.driver._get_volume_with_label_wwn.assert_called_once_with(
|
||||
self.library._get_volume_with_label_wwn.assert_called_once_with(
|
||||
'name2', None)
|
||||
|
||||
def test_get_exist_vol_with_manage_ref(self):
|
||||
fake_ret_vol = {'id': 'right'}
|
||||
self.driver._get_volume_with_label_wwn = mock.Mock(
|
||||
self.library._get_volume_with_label_wwn = mock.Mock(
|
||||
return_value=fake_ret_vol)
|
||||
actual_vol = self.driver._get_existing_vol_with_manage_ref(
|
||||
actual_vol = self.library._get_existing_vol_with_manage_ref(
|
||||
{'id': 'id2'}, {'source-name': 'name2'})
|
||||
self.driver._get_volume_with_label_wwn.assert_called_once_with(
|
||||
self.library._get_volume_with_label_wwn.assert_called_once_with(
|
||||
'name2', None)
|
||||
self.assertEqual(fake_ret_vol, actual_vol)
|
||||
|
||||
@mock.patch.object(utils, 'convert_uuid_to_es_fmt')
|
||||
def test_manage_existing_same_label(self, mock_convert_es_fmt):
|
||||
self.driver._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
self.library._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
return_value=self.fake_ret_vol)
|
||||
mock_convert_es_fmt.return_value = 'label'
|
||||
self.driver.manage_existing(self.volume, self.fake_ref)
|
||||
self.driver._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.library._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.volume, self.fake_ref)
|
||||
mock_convert_es_fmt.assert_called_once_with(
|
||||
'114774fb-e15a-4fae-8ee2-c9723e3645ef')
|
||||
|
||||
@mock.patch.object(utils, 'convert_uuid_to_es_fmt')
|
||||
def test_manage_existing_new(self, mock_convert_es_fmt):
|
||||
self.driver._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
self.library._get_existing_vol_with_manage_ref = mock.Mock(
|
||||
return_value=self.fake_ret_vol)
|
||||
mock_convert_es_fmt.return_value = 'vol_label'
|
||||
self.driver._client.update_volume = mock.Mock(
|
||||
self.library._client.update_volume = mock.Mock(
|
||||
return_value={'id': 'update', 'worldWideName': 'wwn'})
|
||||
self.driver.manage_existing(self.volume, self.fake_ref)
|
||||
self.driver._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.library._get_existing_vol_with_manage_ref.assert_called_once_with(
|
||||
self.volume, self.fake_ref)
|
||||
mock_convert_es_fmt.assert_called_once_with(
|
||||
'114774fb-e15a-4fae-8ee2-c9723e3645ef')
|
||||
self.driver._client.update_volume.assert_called_once_with(
|
||||
self.library._client.update_volume.assert_called_once_with(
|
||||
'vol_id', 'vol_label')
|
||||
|
||||
@mock.patch.object(iscsi.LOG, 'info')
|
||||
@mock.patch.object(library.LOG, 'info')
|
||||
def test_unmanage(self, log_info):
|
||||
self.driver._get_volume = mock.Mock(return_value=self.fake_ret_vol)
|
||||
self.library._get_volume = mock.Mock(return_value=self.fake_ret_vol)
|
||||
self.driver.unmanage(self.volume)
|
||||
self.driver._get_volume.assert_called_once_with(
|
||||
self.library._get_volume.assert_called_once_with(
|
||||
'114774fb-e15a-4fae-8ee2-c9723e3645ef')
|
||||
self.assertEqual(1, log_info.call_count)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# Copyright (c) 2015 Alex Meade. All rights reserved.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from cinder import test
|
||||
import cinder.volume.drivers.netapp.eseries.iscsi_driver as iscsi
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
|
||||
|
||||
class NetAppESeriesISCSIDriverTestCase(test.TestCase):
|
||||
|
||||
@mock.patch.object(na_utils, 'validate_instantiation')
|
||||
def test_instantiation(self, mock_validate_instantiation):
|
||||
iscsi.NetAppEseriesISCSIDriver(configuration=mock.Mock())
|
||||
|
||||
self.assertTrue(mock_validate_instantiation.called)
|
|
@ -14,9 +14,6 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""
|
||||
Mock unit tests for the NetApp E-series iscsi driver
|
||||
"""
|
||||
|
||||
import copy
|
||||
|
||||
|
@ -30,7 +27,7 @@ from cinder.tests.unit.volume.drivers.netapp.eseries import fakes as \
|
|||
eseries_fakes
|
||||
from cinder.volume.drivers.netapp.eseries import client as es_client
|
||||
from cinder.volume.drivers.netapp.eseries import host_mapper
|
||||
from cinder.volume.drivers.netapp.eseries import iscsi as es_iscsi
|
||||
from cinder.volume.drivers.netapp.eseries import library
|
||||
from cinder.volume.drivers.netapp.eseries import utils
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
|
||||
|
@ -48,24 +45,24 @@ def get_fake_volume():
|
|||
}
|
||||
|
||||
|
||||
class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
||||
class NetAppEseriesLibraryTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(NetAppEseriesISCSIDriverTestCase, self).setUp()
|
||||
super(NetAppEseriesLibraryTestCase, self).setUp()
|
||||
|
||||
kwargs = {'configuration':
|
||||
eseries_fakes.create_configuration_eseries()}
|
||||
|
||||
self.driver = es_iscsi.NetAppEseriesISCSIDriver(**kwargs)
|
||||
self.driver._client = eseries_fakes.FakeEseriesClient()
|
||||
self.driver.check_for_setup_error()
|
||||
self.library = library.NetAppESeriesLibrary('FAKE', **kwargs)
|
||||
self.library._client = eseries_fakes.FakeEseriesClient()
|
||||
self.library.check_for_setup_error()
|
||||
|
||||
def test_do_setup(self):
|
||||
self.mock_object(es_iscsi.NetAppEseriesISCSIDriver,
|
||||
self.mock_object(self.library,
|
||||
'_check_mode_get_or_register_storage_system')
|
||||
self.mock_object(es_client, 'RestClient',
|
||||
eseries_fakes.FakeEseriesClient)
|
||||
mock_check_flags = self.mock_object(na_utils, 'check_flags')
|
||||
self.driver.do_setup(mock.Mock())
|
||||
self.library.do_setup(mock.Mock())
|
||||
|
||||
self.assertTrue(mock_check_flags.called)
|
||||
|
||||
|
@ -73,21 +70,21 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'driveMediaType': 'ssd'}]
|
||||
|
||||
self.driver._get_storage_pools = mock.Mock(return_value=['test_vg1'])
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=[])
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._get_storage_pools = mock.Mock(return_value=['test_vg1'])
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=[])
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
self.driver._update_ssc_info()
|
||||
self.library._update_ssc_info()
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'SSD'}},
|
||||
self.driver._ssc_stats)
|
||||
self.library._ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_types_ssd(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'driveMediaType': 'ssd'}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'SSD'}},
|
||||
ssc_stats)
|
||||
|
@ -95,9 +92,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_scsi(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': 'scsi'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'SCSI'}},
|
||||
ssc_stats)
|
||||
|
@ -105,9 +102,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_fcal(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': 'fibre'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'FCAL'}},
|
||||
ssc_stats)
|
||||
|
@ -115,9 +112,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_sata(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': 'sata'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'SATA'}},
|
||||
ssc_stats)
|
||||
|
@ -125,9 +122,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_sas(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': 'sas'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'SAS'}},
|
||||
ssc_stats)
|
||||
|
@ -135,9 +132,9 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_unknown(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': 'unknown'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'unknown'}},
|
||||
ssc_stats)
|
||||
|
@ -145,54 +142,54 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_types_undefined(self):
|
||||
drives = [{'currentVolumeGroupRef': 'test_vg1',
|
||||
'interfaceType': {'driveType': '__UNDEFINED'}}]
|
||||
self.driver._client.list_drives = mock.Mock(return_value=drives)
|
||||
self.library._client.list_drives = mock.Mock(return_value=drives)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_types(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_types(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_type': 'unknown'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_encryption_SecType_enabled(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'enabled'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_encryption': 'true'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_encryption_SecType_unknown(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'unknown'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_encryption': 'false'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_encryption_SecType_none(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'none'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_encryption': 'false'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_encryption_SecType_capable(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'capable'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_encryption': 'false'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_update_ssc_disk_encryption_SecType_garbage(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'garbage'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1'])
|
||||
|
||||
self.assertRaises(TypeError, 'test_vg1',
|
||||
{'netapp_disk_encryption': 'false'}, ssc_stats)
|
||||
|
@ -200,102 +197,104 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
def test_update_ssc_disk_encryption_multiple(self):
|
||||
pools = [{'volumeGroupRef': 'test_vg1', 'securityType': 'none'},
|
||||
{'volumeGroupRef': 'test_vg2', 'securityType': 'enabled'}]
|
||||
self.driver._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
self.library._client.list_storage_pools = mock.Mock(return_value=pools)
|
||||
|
||||
ssc_stats = self.driver._update_ssc_disk_encryption(['test_vg1',
|
||||
'test_vg2'])
|
||||
ssc_stats = self.library._update_ssc_disk_encryption(['test_vg1',
|
||||
'test_vg2'])
|
||||
|
||||
self.assertEqual({'test_vg1': {'netapp_disk_encryption': 'false'},
|
||||
'test_vg2': {'netapp_disk_encryption': 'true'}},
|
||||
ssc_stats)
|
||||
|
||||
def test_terminate_connection_no_hosts(self):
|
||||
def test_terminate_connection_iscsi_no_hosts(self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
|
||||
self.mock_object(self.driver._client, 'list_hosts',
|
||||
self.mock_object(self.library._client, 'list_hosts',
|
||||
mock.Mock(return_value=[]))
|
||||
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.driver.terminate_connection,
|
||||
self.library.terminate_connection_iscsi,
|
||||
get_fake_volume(),
|
||||
connector)
|
||||
|
||||
def test_terminate_connection_volume_not_mapped(self):
|
||||
def test_terminate_connection_iscsi_volume_not_mapped(self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
err = self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver.terminate_connection,
|
||||
self.library.terminate_connection_iscsi,
|
||||
get_fake_volume(),
|
||||
connector)
|
||||
self.assertIn("not currently mapped to host", six.text_type(err))
|
||||
|
||||
def test_terminate_connection_volume_mapped(self):
|
||||
def test_terminate_connection_iscsi_volume_mapped(self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
fake_eseries_volume = copy.deepcopy(eseries_fakes.VOLUME)
|
||||
fake_eseries_volume['listOfMappings'] = [
|
||||
eseries_fakes.VOLUME_MAPPING
|
||||
]
|
||||
self.mock_object(self.driver._client, 'list_volumes',
|
||||
self.mock_object(self.library._client, 'list_volumes',
|
||||
mock.Mock(return_value=[fake_eseries_volume]))
|
||||
self.mock_object(host_mapper, 'unmap_volume_from_host')
|
||||
|
||||
self.driver.terminate_connection(get_fake_volume(), connector)
|
||||
self.library.terminate_connection_iscsi(get_fake_volume(), connector)
|
||||
|
||||
self.assertTrue(host_mapper.unmap_volume_from_host.called)
|
||||
|
||||
def test_terminate_connection_volume_not_mapped_initiator_does_not_exist(
|
||||
def test_terminate_connection_iscsi_not_mapped_initiator_does_not_exist(
|
||||
self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
self.mock_object(self.driver._client, 'list_hosts',
|
||||
self.mock_object(self.library._client, 'list_hosts',
|
||||
mock.Mock(return_value=[eseries_fakes.HOST_2]))
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.driver.terminate_connection,
|
||||
self.library.terminate_connection_iscsi,
|
||||
get_fake_volume(),
|
||||
connector)
|
||||
|
||||
def test_initialize_connection_volume_not_mapped(self):
|
||||
def test_initialize_connection_iscsi_volume_not_mapped(self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
self.mock_object(self.driver._client, 'get_volume_mappings',
|
||||
self.mock_object(self.library._client, 'get_volume_mappings',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(host_mapper, 'map_volume_to_single_host',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.initialize_connection_iscsi(get_fake_volume(), connector)
|
||||
|
||||
self.assertTrue(self.driver._client.get_volume_mappings.called)
|
||||
self.assertTrue(self.library._client.get_volume_mappings.called)
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
def test_initialize_connection_volume_not_mapped_host_does_not_exist(self):
|
||||
def test_initialize_connection_iscsi_volume_not_mapped_host_does_not_exist(
|
||||
self):
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
self.mock_object(self.driver._client, 'get_volume_mappings',
|
||||
self.mock_object(self.library._client, 'get_volume_mappings',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(self.driver._client, 'list_hosts',
|
||||
self.mock_object(self.library._client, 'list_hosts',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(self.driver._client, 'create_host_with_port',
|
||||
self.mock_object(self.library._client, 'create_host_with_port',
|
||||
mock.Mock(return_value=eseries_fakes.HOST))
|
||||
self.mock_object(host_mapper, 'map_volume_to_single_host',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.initialize_connection_iscsi(get_fake_volume(), connector)
|
||||
|
||||
self.assertTrue(self.driver._client.get_volume_mappings.called)
|
||||
self.assertTrue(self.driver._client.list_hosts.called)
|
||||
self.assertTrue(self.driver._client.create_host_with_port.called)
|
||||
self.assertTrue(self.library._client.get_volume_mappings.called)
|
||||
self.assertTrue(self.library._client.list_hosts.called)
|
||||
self.assertTrue(self.library._client.create_host_with_port.called)
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
def test_initialize_connection_volume_already_mapped_to_target_host(self):
|
||||
def test_initialize_connection_iscsi_volume_already_mapped_to_target_host(
|
||||
self):
|
||||
"""Should be a no-op"""
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
self.mock_object(host_mapper, 'map_volume_to_single_host',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.initialize_connection_iscsi(get_fake_volume(), connector)
|
||||
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
def test_initialize_connection_volume_mapped_to_another_host(self):
|
||||
def test_initialize_connection_iscsi_volume_mapped_to_another_host(self):
|
||||
"""Should raise error saying multiattach not enabled"""
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
fake_mapping_to_other_host = copy.deepcopy(
|
||||
|
@ -307,38 +306,38 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
|
|||
side_effect=exception.NetAppDriverException))
|
||||
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver.initialize_connection,
|
||||
self.library.initialize_connection_iscsi,
|
||||
get_fake_volume(), connector)
|
||||
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
|
||||
class NetAppEseriesISCSIDriverMultiAttachTestCase(test.TestCase):
|
||||
class NetAppEseriesLibraryMultiAttachTestCase(test.TestCase):
|
||||
"""Test driver behavior when the netapp_enable_multiattach
|
||||
configuration option is True.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(NetAppEseriesISCSIDriverMultiAttachTestCase, self).setUp()
|
||||
super(NetAppEseriesLibraryMultiAttachTestCase, self).setUp()
|
||||
config = eseries_fakes.create_configuration_eseries()
|
||||
config.netapp_enable_multiattach = True
|
||||
|
||||
kwargs = {'configuration': config}
|
||||
|
||||
self.driver = es_iscsi.NetAppEseriesISCSIDriver(**kwargs)
|
||||
self.driver._client = eseries_fakes.FakeEseriesClient()
|
||||
self.driver.check_for_setup_error()
|
||||
self.library = library.NetAppESeriesLibrary("FAKE", **kwargs)
|
||||
self.library._client = eseries_fakes.FakeEseriesClient()
|
||||
self.library.check_for_setup_error()
|
||||
|
||||
def test_do_setup_host_group_already_exists(self):
|
||||
mock_check_flags = self.mock_object(na_utils, 'check_flags')
|
||||
self.mock_object(es_iscsi.NetAppEseriesISCSIDriver,
|
||||
self.mock_object(self.library,
|
||||
'_check_mode_get_or_register_storage_system')
|
||||
fake_rest_client = eseries_fakes.FakeEseriesClient()
|
||||
self.mock_object(self.driver, '_create_rest_client',
|
||||
self.mock_object(self.library, '_create_rest_client',
|
||||
mock.Mock(return_value=fake_rest_client))
|
||||
mock_create = self.mock_object(fake_rest_client, 'create_host_group')
|
||||
|
||||
self.driver.do_setup(mock.Mock())
|
||||
self.library.do_setup(mock.Mock())
|
||||
|
||||
self.assertTrue(mock_check_flags.called)
|
||||
self.assertFalse(mock_create.call_count)
|
||||
|
@ -346,178 +345,180 @@ class NetAppEseriesISCSIDriverMultiAttachTestCase(test.TestCase):
|
|||
def test_do_setup_host_group_does_not_exist(self):
|
||||
mock_check_flags = self.mock_object(na_utils, 'check_flags')
|
||||
fake_rest_client = eseries_fakes.FakeEseriesClient()
|
||||
self.mock_object(self.driver, '_create_rest_client',
|
||||
self.mock_object(self.library, '_create_rest_client',
|
||||
mock.Mock(return_value=fake_rest_client))
|
||||
mock_get_host_group = self.mock_object(
|
||||
fake_rest_client, "get_host_group_by_name",
|
||||
mock.Mock(side_effect=exception.NotFound))
|
||||
self.mock_object(es_iscsi.NetAppEseriesISCSIDriver,
|
||||
self.mock_object(self.library,
|
||||
'_check_mode_get_or_register_storage_system')
|
||||
|
||||
self.driver.do_setup(mock.Mock())
|
||||
self.library.do_setup(mock.Mock())
|
||||
|
||||
self.assertTrue(mock_check_flags.called)
|
||||
self.assertTrue(mock_get_host_group.call_count)
|
||||
|
||||
def test_create_volume(self):
|
||||
self.driver._client.create_volume = mock.Mock(
|
||||
self.library._client.create_volume = mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME)
|
||||
|
||||
self.driver.create_volume(get_fake_volume())
|
||||
self.assertTrue(self.driver._client.create_volume.call_count)
|
||||
self.library.create_volume(get_fake_volume())
|
||||
self.assertTrue(self.library._client.create_volume.call_count)
|
||||
|
||||
def test_create_volume_too_many_volumes(self):
|
||||
self.driver._client.list_volumes = mock.Mock(
|
||||
self.library._client.list_volumes = mock.Mock(
|
||||
return_value=[eseries_fakes.VOLUME for __ in
|
||||
range(utils.MAX_LUNS_PER_HOST_GROUP + 1)])
|
||||
self.driver._client.create_volume = mock.Mock(
|
||||
self.library._client.create_volume = mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME)
|
||||
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver.create_volume,
|
||||
self.library.create_volume,
|
||||
get_fake_volume())
|
||||
self.assertFalse(self.driver._client.create_volume.call_count)
|
||||
self.assertFalse(self.library._client.create_volume.call_count)
|
||||
|
||||
def test_create_volume_from_snapshot(self):
|
||||
fake_eseries_volume = copy.deepcopy(eseries_fakes.VOLUME)
|
||||
self.mock_object(self.driver, "_schedule_and_create_volume",
|
||||
self.mock_object(self.library, "_schedule_and_create_volume",
|
||||
mock.Mock(return_value=fake_eseries_volume))
|
||||
self.mock_object(self.driver, "_create_snapshot_volume",
|
||||
self.mock_object(self.library, "_create_snapshot_volume",
|
||||
mock.Mock(return_value=fake_eseries_volume))
|
||||
self.mock_object(self.driver._client, "delete_snapshot_volume")
|
||||
self.mock_object(self.library._client, "delete_snapshot_volume")
|
||||
|
||||
self.driver.create_volume_from_snapshot(
|
||||
self.library.create_volume_from_snapshot(
|
||||
get_fake_volume(), fake_snapshot.fake_snapshot_obj(None))
|
||||
|
||||
self.assertEqual(
|
||||
1, self.driver._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.driver._create_snapshot_volume.call_count)
|
||||
1, self.library._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.library._create_snapshot_volume.call_count)
|
||||
self.assertEqual(
|
||||
1, self.driver._client.delete_snapshot_volume.call_count)
|
||||
1, self.library._client.delete_snapshot_volume.call_count)
|
||||
|
||||
def test_create_volume_from_snapshot_create_fails(self):
|
||||
fake_dest_eseries_volume = copy.deepcopy(eseries_fakes.VOLUME)
|
||||
self.mock_object(self.driver, "_schedule_and_create_volume",
|
||||
self.mock_object(self.library, "_schedule_and_create_volume",
|
||||
mock.Mock(return_value=fake_dest_eseries_volume))
|
||||
self.mock_object(self.driver, "_create_snapshot_volume",
|
||||
self.mock_object(self.library, "_create_snapshot_volume",
|
||||
mock.Mock(side_effect=exception.NetAppDriverException)
|
||||
)
|
||||
self.mock_object(self.driver._client, "delete_snapshot_volume")
|
||||
self.mock_object(self.driver._client, "delete_volume")
|
||||
self.mock_object(self.library._client, "delete_snapshot_volume")
|
||||
self.mock_object(self.library._client, "delete_volume")
|
||||
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver.create_volume_from_snapshot,
|
||||
self.library.create_volume_from_snapshot,
|
||||
get_fake_volume(),
|
||||
fake_snapshot.fake_snapshot_obj(None))
|
||||
|
||||
self.assertEqual(
|
||||
1, self.driver._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.driver._create_snapshot_volume.call_count)
|
||||
1, self.library._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.library._create_snapshot_volume.call_count)
|
||||
self.assertEqual(
|
||||
0, self.driver._client.delete_snapshot_volume.call_count)
|
||||
0, self.library._client.delete_snapshot_volume.call_count)
|
||||
# Ensure the volume we were going to copy to is cleaned up
|
||||
self.driver._client.delete_volume.assert_called_once_with(
|
||||
self.library._client.delete_volume.assert_called_once_with(
|
||||
fake_dest_eseries_volume['volumeRef'])
|
||||
|
||||
def test_create_volume_from_snapshot_copy_job_fails(self):
|
||||
fake_dest_eseries_volume = copy.deepcopy(eseries_fakes.VOLUME)
|
||||
self.mock_object(self.driver, "_schedule_and_create_volume",
|
||||
self.mock_object(self.library, "_schedule_and_create_volume",
|
||||
mock.Mock(return_value=fake_dest_eseries_volume))
|
||||
self.mock_object(self.driver, "_create_snapshot_volume",
|
||||
self.mock_object(self.library, "_create_snapshot_volume",
|
||||
mock.Mock(return_value=fake_dest_eseries_volume))
|
||||
self.mock_object(self.driver._client, "delete_snapshot_volume")
|
||||
self.mock_object(self.driver._client, "delete_volume")
|
||||
self.mock_object(self.library._client, "delete_snapshot_volume")
|
||||
self.mock_object(self.library._client, "delete_volume")
|
||||
|
||||
fake_failed_volume_copy_job = copy.deepcopy(
|
||||
eseries_fakes.VOLUME_COPY_JOB)
|
||||
fake_failed_volume_copy_job['status'] = 'failed'
|
||||
self.mock_object(self.driver._client,
|
||||
self.mock_object(self.library._client,
|
||||
"create_volume_copy_job",
|
||||
mock.Mock(return_value=fake_failed_volume_copy_job))
|
||||
self.mock_object(self.driver._client,
|
||||
self.mock_object(self.library._client,
|
||||
"list_vol_copy_job",
|
||||
mock.Mock(return_value=fake_failed_volume_copy_job))
|
||||
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.driver.create_volume_from_snapshot,
|
||||
self.library.create_volume_from_snapshot,
|
||||
get_fake_volume(),
|
||||
fake_snapshot.fake_snapshot_obj(None))
|
||||
|
||||
self.assertEqual(
|
||||
1, self.driver._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.driver._create_snapshot_volume.call_count)
|
||||
1, self.library._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.library._create_snapshot_volume.call_count)
|
||||
self.assertEqual(
|
||||
1, self.driver._client.delete_snapshot_volume.call_count)
|
||||
1, self.library._client.delete_snapshot_volume.call_count)
|
||||
# Ensure the volume we were going to copy to is cleaned up
|
||||
self.driver._client.delete_volume.assert_called_once_with(
|
||||
self.library._client.delete_volume.assert_called_once_with(
|
||||
fake_dest_eseries_volume['volumeRef'])
|
||||
|
||||
def test_create_volume_from_snapshot_fail_to_delete_snapshot_volume(self):
|
||||
fake_dest_eseries_volume = copy.deepcopy(eseries_fakes.VOLUME)
|
||||
fake_dest_eseries_volume['volumeRef'] = 'fake_volume_ref'
|
||||
self.mock_object(self.driver, "_schedule_and_create_volume",
|
||||
self.mock_object(self.library, "_schedule_and_create_volume",
|
||||
mock.Mock(return_value=fake_dest_eseries_volume))
|
||||
self.mock_object(self.driver, "_create_snapshot_volume",
|
||||
self.mock_object(self.library, "_create_snapshot_volume",
|
||||
mock.Mock(return_value=copy.deepcopy(
|
||||
eseries_fakes.VOLUME)))
|
||||
self.mock_object(self.driver._client, "delete_snapshot_volume",
|
||||
self.mock_object(self.library._client, "delete_snapshot_volume",
|
||||
mock.Mock(side_effect=exception.NetAppDriverException)
|
||||
)
|
||||
self.mock_object(self.driver._client, "delete_volume")
|
||||
self.mock_object(self.library._client, "delete_volume")
|
||||
|
||||
self.driver.create_volume_from_snapshot(
|
||||
self.library.create_volume_from_snapshot(
|
||||
get_fake_volume(), fake_snapshot.fake_snapshot_obj(None))
|
||||
|
||||
self.assertEqual(
|
||||
1, self.driver._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.driver._create_snapshot_volume.call_count)
|
||||
1, self.library._schedule_and_create_volume.call_count)
|
||||
self.assertEqual(1, self.library._create_snapshot_volume.call_count)
|
||||
self.assertEqual(
|
||||
1, self.driver._client.delete_snapshot_volume.call_count)
|
||||
1, self.library._client.delete_snapshot_volume.call_count)
|
||||
# Ensure the volume we created is not cleaned up
|
||||
self.assertEqual(0, self.driver._client.delete_volume.call_count)
|
||||
self.assertEqual(0, self.library._client.delete_volume.call_count)
|
||||
|
||||
def test_initialize_connection_volume_not_mapped(self):
|
||||
"""Map the volume directly to destination host.
|
||||
"""
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME_2}
|
||||
self.mock_object(self.driver._client, 'get_volume_mappings',
|
||||
def test_map_volume_to_host_volume_not_mapped(self):
|
||||
"""Map the volume directly to destination host."""
|
||||
self.mock_object(self.library._client, 'get_volume_mappings',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(host_mapper, 'map_volume_to_single_host',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.map_volume_to_host(get_fake_volume(),
|
||||
eseries_fakes.VOLUME,
|
||||
eseries_fakes.INITIATOR_NAME_2)
|
||||
|
||||
self.assertTrue(self.driver._client.get_volume_mappings.called)
|
||||
self.assertTrue(self.library._client.get_volume_mappings.called)
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
def test_initialize_connection_volume_not_mapped_host_does_not_exist(self):
|
||||
def test_map_volume_to_host_volume_not_mapped_host_does_not_exist(self):
|
||||
"""Should create the host map directly to the host."""
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME_2}
|
||||
self.mock_object(self.driver._client, 'list_hosts',
|
||||
self.mock_object(self.library._client, 'list_hosts',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(self.driver._client, 'create_host_with_port',
|
||||
self.mock_object(self.library._client, 'create_host_with_port',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.HOST_2))
|
||||
self.mock_object(self.driver._client, 'get_volume_mappings',
|
||||
self.mock_object(self.library._client, 'get_volume_mappings',
|
||||
mock.Mock(return_value=[]))
|
||||
self.mock_object(host_mapper, 'map_volume_to_single_host',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.map_volume_to_host(get_fake_volume(),
|
||||
eseries_fakes.VOLUME,
|
||||
eseries_fakes.INITIATOR_NAME_2)
|
||||
|
||||
self.assertTrue(self.driver._client.create_host_with_port.called)
|
||||
self.assertTrue(self.driver._client.get_volume_mappings.called)
|
||||
self.assertTrue(self.library._client.create_host_with_port.called)
|
||||
self.assertTrue(self.library._client.get_volume_mappings.called)
|
||||
self.assertTrue(host_mapper.map_volume_to_single_host.called)
|
||||
|
||||
def test_initialize_connection_volume_already_mapped(self):
|
||||
def test_map_volume_to_host_volume_already_mapped(self):
|
||||
"""Should be a no-op."""
|
||||
connector = {'initiator': eseries_fakes.INITIATOR_NAME}
|
||||
self.mock_object(host_mapper, 'map_volume_to_multiple_hosts',
|
||||
mock.Mock(
|
||||
return_value=eseries_fakes.VOLUME_MAPPING))
|
||||
|
||||
self.driver.initialize_connection(get_fake_volume(), connector)
|
||||
self.library.map_volume_to_host(get_fake_volume(),
|
||||
eseries_fakes.VOLUME,
|
||||
eseries_fakes.INITIATOR_NAME)
|
||||
|
||||
self.assertTrue(host_mapper.map_volume_to_multiple_hosts.called)
|
|
@ -49,7 +49,7 @@ NETAPP_UNIFIED_DRIVER_REGISTRY = {
|
|||
},
|
||||
'eseries':
|
||||
{
|
||||
'iscsi': ESERIES_PATH + '.iscsi.NetAppEseriesISCSIDriver'
|
||||
'iscsi': ESERIES_PATH + '.iscsi_driver.NetAppEseriesISCSIDriver'
|
||||
}}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
# Copyright (c) 2014 NetApp, Inc. All Rights Reserved.
|
||||
# Copyright (c) 2015 Alex Meade. All Rights Reserved.
|
||||
# Copyright (c) 2015 Rushil Chugh. All Rights Reserved.
|
||||
# Copyright (c) 2015 Navneet Singh. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""
|
||||
iSCSI driver for NetApp E-series storage systems.
|
||||
"""
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.eseries import library
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
DRIVER_NAME = 'NetApp_iSCSI_ESeries'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NetAppEseriesISCSIDriver, self).__init__(*args, **kwargs)
|
||||
na_utils.validate_instantiation(**kwargs)
|
||||
self.library = library.NetAppESeriesLibrary(self.DRIVER_NAME,
|
||||
'iSCSI', **kwargs)
|
||||
|
||||
def do_setup(self, context):
|
||||
self.library.do_setup(context)
|
||||
|
||||
def check_for_setup_error(self):
|
||||
self.library.check_for_setup_error()
|
||||
|
||||
def create_volume(self, volume):
|
||||
self.library.create_volume(volume)
|
||||
|
||||
def create_volume_from_snapshot(self, volume, snapshot):
|
||||
self.library.create_volume_from_snapshot(volume, snapshot)
|
||||
|
||||
def create_cloned_volume(self, volume, src_vref):
|
||||
self.library.create_cloned_volume(volume, src_vref)
|
||||
|
||||
def delete_volume(self, volume):
|
||||
self.library.delete_volume(volume)
|
||||
|
||||
def create_snapshot(self, snapshot):
|
||||
self.library.create_snapshot(snapshot)
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
self.library.delete_snapshot(snapshot)
|
||||
|
||||
def get_volume_stats(self, refresh=False):
|
||||
return self.library.get_volume_stats(refresh)
|
||||
|
||||
def extend_volume(self, volume, new_size):
|
||||
self.library.extend_volume(volume, new_size)
|
||||
|
||||
def ensure_export(self, context, volume):
|
||||
return self.library.ensure_export(context, volume)
|
||||
|
||||
def create_export(self, context, volume):
|
||||
return self.library.create_export(context, volume)
|
||||
|
||||
def remove_export(self, context, volume):
|
||||
self.library.remove_export(context, volume)
|
||||
|
||||
def manage_existing(self, volume, existing_ref):
|
||||
return self.library.manage_existing(volume, existing_ref)
|
||||
|
||||
def manage_existing_get_size(self, volume, existing_ref):
|
||||
return self.library.manage_existing_get_size(volume, existing_ref)
|
||||
|
||||
def unmanage(self, volume):
|
||||
return self.library.unmanage(volume)
|
||||
|
||||
def initialize_connection(self, volume, connector):
|
||||
return self.library.initialize_connection_iscsi(volume, connector)
|
||||
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
return self.library.terminate_connection_iscsi(volume, connector,
|
||||
**kwargs)
|
||||
|
||||
def get_pool(self, volume):
|
||||
return self.library.get_pool(volume)
|
|
@ -14,9 +14,6 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""
|
||||
iSCSI driver for NetApp E-series storage systems.
|
||||
"""
|
||||
|
||||
import copy
|
||||
import math
|
||||
|
@ -34,7 +31,6 @@ from cinder import exception
|
|||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.openstack.common import loopingcall
|
||||
from cinder import utils as cinder_utils
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.netapp.eseries import client
|
||||
from cinder.volume.drivers.netapp.eseries import exception as eseries_exc
|
||||
from cinder.volume.drivers.netapp.eseries import host_mapper
|
||||
|
@ -46,7 +42,6 @@ from cinder.volume import utils as volume_utils
|
|||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(na_opts.netapp_basicauth_opts)
|
||||
CONF.register_opts(na_opts.netapp_connection_opts)
|
||||
|
@ -55,7 +50,7 @@ CONF.register_opts(na_opts.netapp_transport_opts)
|
|||
CONF.register_opts(na_opts.netapp_san_opts)
|
||||
|
||||
|
||||
class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
||||
class NetAppESeriesLibrary(object):
|
||||
"""Executes commands relating to Volumes."""
|
||||
|
||||
VERSION = "1.0.0"
|
||||
|
@ -97,9 +92,9 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
|
||||
DEFAULT_HOST_TYPE = 'linux_dm_mp'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NetAppEseriesISCSIDriver, self).__init__(*args, **kwargs)
|
||||
na_utils.validate_instantiation(**kwargs)
|
||||
def __init__(self, driver_name, driver_protocol="iSCSI",
|
||||
configuration=None, **kwargs):
|
||||
self.configuration = configuration
|
||||
self.configuration.append_config_values(na_opts.netapp_basicauth_opts)
|
||||
self.configuration.append_config_values(
|
||||
na_opts.netapp_connection_opts)
|
||||
|
@ -108,6 +103,9 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
self.configuration.append_config_values(na_opts.netapp_san_opts)
|
||||
self._backend_name = self.configuration.safe_get(
|
||||
"volume_backend_name") or "NetApp_ESeries"
|
||||
self.driver_name = driver_name
|
||||
self.driver_protocol = driver_protocol
|
||||
self._stats = {}
|
||||
self._ssc_stats = {}
|
||||
|
||||
def do_setup(self, context):
|
||||
|
@ -457,7 +455,8 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
|
||||
def create_cloned_volume(self, volume, src_vref):
|
||||
"""Creates a clone of the specified volume."""
|
||||
snapshot = {'id': uuid.uuid4(), 'volume_id': src_vref['id']}
|
||||
snapshot = {'id': uuid.uuid4(), 'volume_id': src_vref['id'],
|
||||
'volume': src_vref}
|
||||
self.create_snapshot(snapshot)
|
||||
try:
|
||||
self.create_volume_from_snapshot(volume, snapshot)
|
||||
|
@ -481,7 +480,7 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
"""Creates a snapshot."""
|
||||
snap_grp, snap_image = None, None
|
||||
snapshot_name = utils.convert_uuid_to_es_fmt(snapshot['id'])
|
||||
os_vol = self.db.volume_get(self.context, snapshot['volume_id'])
|
||||
os_vol = snapshot['volume']
|
||||
vol = self._get_volume(os_vol['name_id'])
|
||||
vol_size_gb = int(vol['totalSizeInBytes']) / units.Gi
|
||||
pools = self._get_sorted_available_storage_pools(vol_size_gb)
|
||||
|
@ -517,12 +516,10 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
"""Removes an export for a volume."""
|
||||
pass
|
||||
|
||||
def initialize_connection(self, volume, connector):
|
||||
"""Allow connection to connector and return connection info."""
|
||||
initiator_name = connector['initiator']
|
||||
eseries_vol = self._get_volume(volume['name_id'])
|
||||
def map_volume_to_host(self, volume, eseries_volume, initiator_name):
|
||||
"""Ensures the specified initiator has access to the volume."""
|
||||
existing_maps = host_mapper.get_host_mapping_for_vol_frm_array(
|
||||
self._client, eseries_vol)
|
||||
self._client, eseries_volume)
|
||||
host = self._get_or_create_host(initiator_name, self.host_type)
|
||||
# There can only be one or zero mappings on a volume in E-Series
|
||||
current_map = existing_maps[0] if existing_maps else None
|
||||
|
@ -531,13 +528,20 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
self._ensure_multi_attach_host_group_exists()
|
||||
mapping = host_mapper.map_volume_to_multiple_hosts(self._client,
|
||||
volume,
|
||||
eseries_vol,
|
||||
eseries_volume,
|
||||
host,
|
||||
current_map)
|
||||
else:
|
||||
mapping = host_mapper.map_volume_to_single_host(
|
||||
self._client, volume, eseries_vol, host, current_map,
|
||||
self._client, volume, eseries_volume, host, current_map,
|
||||
self.configuration.netapp_enable_multiattach)
|
||||
return mapping
|
||||
|
||||
def initialize_connection_iscsi(self, volume, connector):
|
||||
"""Allow connection to connector and return connection info."""
|
||||
initiator_name = connector['initiator']
|
||||
eseries_vol = self._get_volume(volume['name_id'])
|
||||
mapping = self.map_volume_to_host(volume, eseries_vol, initiator_name)
|
||||
|
||||
lun_id = mapping['lun']
|
||||
msg_fmt = {'id': volume['id'], 'initiator_name': initiator_name}
|
||||
|
@ -644,7 +648,7 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
return ht
|
||||
raise exception.NotFound(_("Host type %s not supported.") % host_type)
|
||||
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
def terminate_connection_iscsi(self, volume, connector, **kwargs):
|
||||
"""Disallow connection from connector."""
|
||||
eseries_vol = self._get_volume(volume['name_id'])
|
||||
initiator = connector['initiator']
|
||||
|
@ -675,7 +679,7 @@ class NetAppEseriesISCSIDriver(driver.ISCSIDriver):
|
|||
data["volume_backend_name"] = self._backend_name
|
||||
data["vendor_name"] = "NetApp"
|
||||
data["driver_version"] = self.VERSION
|
||||
data["storage_protocol"] = "iSCSI"
|
||||
data["storage_protocol"] = self.driver_protocol
|
||||
data["pools"] = []
|
||||
|
||||
for storage_pool in self._get_storage_pools():
|
Loading…
Reference in New Issue