libvirt: move LibvirtNETVolumeDriver into it's own module
Introduces the LibvirtISCSIVolumeBaseTestCase class for the iSCSI-based volume driver tests like iSCSI and the Network volume driver (iSCSI volume driver changes yet to come). There is some additional refactor cleanup that can be done here since this code is a bit hacky with the protocol checks and secret CRUD ops in the libvirt host module, but that's reserved for later changes. Part of blueprint consolidate-libvirt-fs-volume-drivers Change-Id: I31404d057d596473a9c0960e2696affb1e35e132
This commit is contained in:
parent
1106704256
commit
d5bd7d44eb
202
nova/tests/unit/virt/libvirt/volume/test_net.py
Normal file
202
nova/tests/unit/virt/libvirt/volume/test_net.py
Normal file
@ -0,0 +1,202 @@
|
||||
# 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 oslo_config import cfg
|
||||
|
||||
from nova.tests.unit.virt.libvirt.volume import test_volume
|
||||
from nova.virt.libvirt import host
|
||||
from nova.virt.libvirt.volume import net
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('rbd_user', 'nova.virt.libvirt.volume.net', group='libvirt')
|
||||
CONF.import_opt('rbd_secret_uuid', 'nova.virt.libvirt.volume.net',
|
||||
group='libvirt')
|
||||
|
||||
|
||||
class LibvirtNetVolumeDriverTestCase(
|
||||
test_volume.LibvirtISCSIVolumeBaseTestCase):
|
||||
"""Tests the libvirt network volume driver."""
|
||||
|
||||
def _assertNetworkAndProtocolEquals(self, tree):
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
|
||||
rbd_name = '%s/%s' % ('rbd', self.name)
|
||||
self.assertEqual(tree.find('./source').get('name'), rbd_name)
|
||||
|
||||
def _assertISCSINetworkAndProtocolEquals(self, tree):
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'iscsi')
|
||||
iscsi_name = '%s/%s' % (self.iqn, self.vol['id'])
|
||||
self.assertEqual(tree.find('./source').get('name'), iscsi_name)
|
||||
|
||||
def sheepdog_connection(self, volume):
|
||||
return {
|
||||
'driver_volume_type': 'sheepdog',
|
||||
'data': {
|
||||
'name': volume['name']
|
||||
}
|
||||
}
|
||||
|
||||
def test_libvirt_sheepdog_driver(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.sheepdog_connection(self.vol)
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'sheepdog')
|
||||
self.assertEqual(tree.find('./source').get('name'), self.name)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def rbd_connection(self, volume):
|
||||
return {
|
||||
'driver_volume_type': 'rbd',
|
||||
'data': {
|
||||
'name': '%s/%s' % ('rbd', volume['name']),
|
||||
'auth_enabled': CONF.libvirt.rbd_secret_uuid is not None,
|
||||
'auth_username': CONF.libvirt.rbd_user,
|
||||
'secret_type': 'ceph',
|
||||
'secret_uuid': CONF.libvirt.rbd_secret_uuid,
|
||||
'qos_specs': {
|
||||
'total_bytes_sec': '1048576',
|
||||
'read_iops_sec': '500',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def test_libvirt_rbd_driver(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./source/auth'))
|
||||
self.assertEqual('1048576', tree.find('./iotune/total_bytes_sec').text)
|
||||
self.assertEqual('500', tree.find('./iotune/read_iops_sec').text)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_hosts(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
hosts = ['example.com', '1.2.3.4', '::1']
|
||||
ports = [None, '6790', '6791']
|
||||
connection_info['data']['hosts'] = hosts
|
||||
connection_info['data']['ports'] = ports
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./source/auth'))
|
||||
found_hosts = tree.findall('./source/host')
|
||||
self.assertEqual([host.get('name') for host in found_hosts], hosts)
|
||||
self.assertEqual([host.get('port') for host in found_hosts], ports)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_enabled(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = True
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), self.user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), self.uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_enabled_flags_override(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = True
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
flags_uuid = '37152720-1785-11e2-a740-af0c1d8b8e4b'
|
||||
flags_user = 'bar'
|
||||
self.flags(rbd_user=flags_user,
|
||||
rbd_secret_uuid=flags_uuid,
|
||||
group='libvirt')
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), flags_uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_disabled(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = False
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./auth'))
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_disabled_flags_override(self):
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = False
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
# NOTE: Supplying the rbd_secret_uuid will enable authentication
|
||||
# locally in nova-compute even if not enabled in nova-volume/cinder
|
||||
flags_uuid = '37152720-1785-11e2-a740-af0c1d8b8e4b'
|
||||
flags_user = 'bar'
|
||||
self.flags(rbd_user=flags_user,
|
||||
rbd_secret_uuid=flags_uuid,
|
||||
group='libvirt')
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), flags_uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
@mock.patch.object(host.Host, 'find_secret')
|
||||
@mock.patch.object(host.Host, 'create_secret')
|
||||
@mock.patch.object(host.Host, 'delete_secret')
|
||||
def test_libvirt_iscsi_net_driver(self, mock_delete, mock_create,
|
||||
mock_find):
|
||||
mock_find.return_value = test_volume.FakeSecret()
|
||||
mock_create.return_value = test_volume.FakeSecret()
|
||||
libvirt_driver = net.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.iscsi_connection(self.vol, self.location,
|
||||
self.iqn, auth=True)
|
||||
secret_type = 'iscsi'
|
||||
flags_user = connection_info['data']['auth_username']
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertISCSINetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'),
|
||||
test_volume.SECRET_UUID)
|
||||
libvirt_driver.disconnect_volume(connection_info, 'vde')
|
@ -15,7 +15,6 @@
|
||||
|
||||
import mock
|
||||
from os_brick.initiator import connector
|
||||
from oslo_config import cfg
|
||||
|
||||
from nova import exception
|
||||
from nova import test
|
||||
@ -24,7 +23,6 @@ from nova import utils
|
||||
from nova.virt.libvirt import host
|
||||
from nova.virt.libvirt.volume import volume
|
||||
|
||||
CONF = cfg.CONF
|
||||
SECRET_UUID = '2a0a0d6c-babf-454d-b93e-9ac9957b95e0'
|
||||
|
||||
|
||||
@ -96,19 +94,37 @@ class LibvirtVolumeBaseTestCase(test.NoDBTestCase):
|
||||
self.assertEqual(tree.find('./source').get('file'), file_path)
|
||||
|
||||
|
||||
class LibvirtVolumeTestCase(LibvirtVolumeBaseTestCase):
|
||||
class LibvirtISCSIVolumeBaseTestCase(LibvirtVolumeBaseTestCase):
|
||||
"""Contains common setup and helper methods for iSCSI volume tests."""
|
||||
|
||||
def _assertNetworkAndProtocolEquals(self, tree):
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'rbd')
|
||||
rbd_name = '%s/%s' % ('rbd', self.name)
|
||||
self.assertEqual(tree.find('./source').get('name'), rbd_name)
|
||||
def iscsi_connection(self, volume, location, iqn, auth=False,
|
||||
transport=None):
|
||||
dev_name = 'ip-%s-iscsi-%s-lun-1' % (location, iqn)
|
||||
if transport is not None:
|
||||
dev_name = 'pci-0000:00:00.0-' + dev_name
|
||||
dev_path = '/dev/disk/by-path/%s' % (dev_name)
|
||||
ret = {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': {
|
||||
'volume_id': volume['id'],
|
||||
'target_portal': location,
|
||||
'target_iqn': iqn,
|
||||
'target_lun': 1,
|
||||
'device_path': dev_path,
|
||||
'qos_specs': {
|
||||
'total_bytes_sec': '102400',
|
||||
'read_iops_sec': '200',
|
||||
}
|
||||
}
|
||||
}
|
||||
if auth:
|
||||
ret['data']['auth_method'] = 'CHAP'
|
||||
ret['data']['auth_username'] = 'foo'
|
||||
ret['data']['auth_password'] = 'bar'
|
||||
return ret
|
||||
|
||||
def _assertISCSINetworkAndProtocolEquals(self, tree):
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'iscsi')
|
||||
iscsi_name = '%s/%s' % (self.iqn, self.vol['id'])
|
||||
self.assertEqual(tree.find('./source').get('name'), iscsi_name)
|
||||
|
||||
class LibvirtVolumeTestCase(LibvirtISCSIVolumeBaseTestCase):
|
||||
|
||||
def _assertDiskInfoEquals(self, tree, disk_info):
|
||||
self.assertEqual(tree.get('device'), disk_info['type'])
|
||||
@ -248,32 +264,6 @@ class LibvirtVolumeTestCase(LibvirtVolumeBaseTestCase):
|
||||
readonly = tree.find('./readonly')
|
||||
self.assertIsNotNone(readonly)
|
||||
|
||||
def iscsi_connection(self, volume, location, iqn, auth=False,
|
||||
transport=None):
|
||||
dev_name = 'ip-%s-iscsi-%s-lun-1' % (location, iqn)
|
||||
if transport is not None:
|
||||
dev_name = 'pci-0000:00:00.0-' + dev_name
|
||||
dev_path = '/dev/disk/by-path/%s' % (dev_name)
|
||||
ret = {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': {
|
||||
'volume_id': volume['id'],
|
||||
'target_portal': location,
|
||||
'target_iqn': iqn,
|
||||
'target_lun': 1,
|
||||
'device_path': dev_path,
|
||||
'qos_specs': {
|
||||
'total_bytes_sec': '102400',
|
||||
'read_iops_sec': '200',
|
||||
}
|
||||
}
|
||||
}
|
||||
if auth:
|
||||
ret['data']['auth_method'] = 'CHAP'
|
||||
ret['data']['auth_username'] = 'foo'
|
||||
ret['data']['auth_password'] = 'bar'
|
||||
return ret
|
||||
|
||||
def iscsi_connection_discovery_chap_enable(self, volume, location, iqn):
|
||||
dev_name = 'ip-%s-iscsi-%s-lun-1' % (location, iqn)
|
||||
dev_path = '/dev/disk/by-path/%s' % (dev_name)
|
||||
@ -356,164 +346,3 @@ Setting up iSCSI targets: unused
|
||||
# we don't care what the log message is, we just want to make sure
|
||||
# our stub method is called which asserts the password is scrubbed
|
||||
self.assertTrue(debug_mock.called)
|
||||
|
||||
def sheepdog_connection(self, volume):
|
||||
return {
|
||||
'driver_volume_type': 'sheepdog',
|
||||
'data': {
|
||||
'name': volume['name']
|
||||
}
|
||||
}
|
||||
|
||||
def test_libvirt_sheepdog_driver(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.sheepdog_connection(self.vol)
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self.assertEqual(tree.get('type'), 'network')
|
||||
self.assertEqual(tree.find('./source').get('protocol'), 'sheepdog')
|
||||
self.assertEqual(tree.find('./source').get('name'), self.name)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def rbd_connection(self, volume):
|
||||
return {
|
||||
'driver_volume_type': 'rbd',
|
||||
'data': {
|
||||
'name': '%s/%s' % ('rbd', volume['name']),
|
||||
'auth_enabled': CONF.libvirt.rbd_secret_uuid is not None,
|
||||
'auth_username': CONF.libvirt.rbd_user,
|
||||
'secret_type': 'ceph',
|
||||
'secret_uuid': CONF.libvirt.rbd_secret_uuid,
|
||||
'qos_specs': {
|
||||
'total_bytes_sec': '1048576',
|
||||
'read_iops_sec': '500',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def test_libvirt_rbd_driver(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./source/auth'))
|
||||
self.assertEqual('1048576', tree.find('./iotune/total_bytes_sec').text)
|
||||
self.assertEqual('500', tree.find('./iotune/read_iops_sec').text)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_hosts(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
hosts = ['example.com', '1.2.3.4', '::1']
|
||||
ports = [None, '6790', '6791']
|
||||
connection_info['data']['hosts'] = hosts
|
||||
connection_info['data']['ports'] = ports
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./source/auth'))
|
||||
found_hosts = tree.findall('./source/host')
|
||||
self.assertEqual([host.get('name') for host in found_hosts], hosts)
|
||||
self.assertEqual([host.get('port') for host in found_hosts], ports)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_enabled(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = True
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), self.user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), self.uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_enabled_flags_override(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = True
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
flags_uuid = '37152720-1785-11e2-a740-af0c1d8b8e4b'
|
||||
flags_user = 'bar'
|
||||
self.flags(rbd_user=flags_user,
|
||||
rbd_secret_uuid=flags_uuid,
|
||||
group='libvirt')
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), flags_uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_disabled(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = False
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertIsNone(tree.find('./auth'))
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
def test_libvirt_rbd_driver_auth_disabled_flags_override(self):
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.rbd_connection(self.vol)
|
||||
secret_type = 'ceph'
|
||||
connection_info['data']['auth_enabled'] = False
|
||||
connection_info['data']['auth_username'] = self.user
|
||||
connection_info['data']['secret_type'] = secret_type
|
||||
connection_info['data']['secret_uuid'] = self.uuid
|
||||
|
||||
# NOTE: Supplying the rbd_secret_uuid will enable authentication
|
||||
# locally in nova-compute even if not enabled in nova-volume/cinder
|
||||
flags_uuid = '37152720-1785-11e2-a740-af0c1d8b8e4b'
|
||||
flags_user = 'bar'
|
||||
self.flags(rbd_user=flags_user,
|
||||
rbd_secret_uuid=flags_uuid,
|
||||
group='libvirt')
|
||||
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertNetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), flags_uuid)
|
||||
libvirt_driver.disconnect_volume(connection_info, "vde")
|
||||
|
||||
@mock.patch.object(host.Host, 'find_secret')
|
||||
@mock.patch.object(host.Host, 'create_secret')
|
||||
@mock.patch.object(host.Host, 'delete_secret')
|
||||
def test_libvirt_iscsi_net_driver(self, mock_delete, mock_create,
|
||||
mock_find):
|
||||
mock_find.return_value = FakeSecret()
|
||||
mock_create.return_value = FakeSecret()
|
||||
libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn)
|
||||
connection_info = self.iscsi_connection(self.vol, self.location,
|
||||
self.iqn, auth=True)
|
||||
secret_type = 'iscsi'
|
||||
flags_user = connection_info['data']['auth_username']
|
||||
conf = libvirt_driver.get_config(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self._assertISCSINetworkAndProtocolEquals(tree)
|
||||
self.assertEqual(tree.find('./auth').get('username'), flags_user)
|
||||
self.assertEqual(tree.find('./auth/secret').get('type'), secret_type)
|
||||
self.assertEqual(tree.find('./auth/secret').get('uuid'), SECRET_UUID)
|
||||
libvirt_driver.disconnect_volume(connection_info, 'vde')
|
||||
|
@ -277,8 +277,8 @@ libvirt_volume_drivers = [
|
||||
'iser=nova.virt.libvirt.volume.iser.LibvirtISERVolumeDriver',
|
||||
'local=nova.virt.libvirt.volume.volume.LibvirtVolumeDriver',
|
||||
'fake=nova.virt.libvirt.volume.volume.LibvirtFakeVolumeDriver',
|
||||
'rbd=nova.virt.libvirt.volume.volume.LibvirtNetVolumeDriver',
|
||||
'sheepdog=nova.virt.libvirt.volume.volume.LibvirtNetVolumeDriver',
|
||||
'rbd=nova.virt.libvirt.volume.net.LibvirtNetVolumeDriver',
|
||||
'sheepdog=nova.virt.libvirt.volume.net.LibvirtNetVolumeDriver',
|
||||
'nfs=nova.virt.libvirt.volume.nfs.LibvirtNFSVolumeDriver',
|
||||
'smbfs=nova.virt.libvirt.volume.smbfs.LibvirtSMBFSVolumeDriver',
|
||||
'aoe=nova.virt.libvirt.volume.aoe.LibvirtAOEVolumeDriver',
|
||||
|
@ -80,8 +80,8 @@ CONF.import_opt('cipher', 'nova.compute.api',
|
||||
group='ephemeral_storage_encryption')
|
||||
CONF.import_opt('key_size', 'nova.compute.api',
|
||||
group='ephemeral_storage_encryption')
|
||||
CONF.import_opt('rbd_user', 'nova.virt.libvirt.volume.volume', group='libvirt')
|
||||
CONF.import_opt('rbd_secret_uuid', 'nova.virt.libvirt.volume.volume',
|
||||
CONF.import_opt('rbd_user', 'nova.virt.libvirt.volume.net', group='libvirt')
|
||||
CONF.import_opt('rbd_secret_uuid', 'nova.virt.libvirt.volume.net',
|
||||
group='libvirt')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
111
nova/virt/libvirt/volume/net.py
Normal file
111
nova/virt/libvirt/volume/net.py
Normal file
@ -0,0 +1,111 @@
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import utils
|
||||
from nova.virt.libvirt.volume import volume as libvirt_volume
|
||||
|
||||
volume_opts = [
|
||||
cfg.StrOpt('rbd_user',
|
||||
help='The RADOS client name for accessing rbd volumes'),
|
||||
cfg.StrOpt('rbd_secret_uuid',
|
||||
help='The libvirt UUID of the secret for the rbd_user'
|
||||
'volumes'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(volume_opts, 'libvirt')
|
||||
|
||||
|
||||
class LibvirtNetVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver):
|
||||
"""Driver to attach Network volumes to libvirt."""
|
||||
def __init__(self, connection):
|
||||
super(LibvirtNetVolumeDriver,
|
||||
self).__init__(connection, is_block_dev=False)
|
||||
|
||||
def _get_secret_uuid(self, conf, password=None):
|
||||
# TODO(mriedem): Add delegation methods to connection (LibvirtDriver)
|
||||
# to call through for these secret CRUD operations so the volume driver
|
||||
# doesn't need to know the internal attributes of the connection
|
||||
# object.
|
||||
secret = self.connection._host.find_secret(conf.source_protocol,
|
||||
conf.source_name)
|
||||
if secret is None:
|
||||
secret = self.connection._host.create_secret(conf.source_protocol,
|
||||
conf.source_name,
|
||||
password)
|
||||
return secret.UUIDString()
|
||||
|
||||
def _delete_secret_by_name(self, connection_info):
|
||||
source_protocol = connection_info['driver_volume_type']
|
||||
netdisk_properties = connection_info['data']
|
||||
if source_protocol == 'rbd':
|
||||
return
|
||||
elif source_protocol == 'iscsi':
|
||||
usage_type = 'iscsi'
|
||||
usage_name = ("%(target_iqn)s/%(target_lun)s" %
|
||||
netdisk_properties)
|
||||
self.connection._host.delete_secret(usage_type, usage_name)
|
||||
|
||||
def get_config(self, connection_info, disk_info):
|
||||
"""Returns xml for libvirt."""
|
||||
conf = super(LibvirtNetVolumeDriver,
|
||||
self).get_config(connection_info, disk_info)
|
||||
|
||||
netdisk_properties = connection_info['data']
|
||||
conf.source_type = "network"
|
||||
conf.source_protocol = connection_info['driver_volume_type']
|
||||
conf.source_name = netdisk_properties.get('name')
|
||||
conf.source_hosts = netdisk_properties.get('hosts', [])
|
||||
conf.source_ports = netdisk_properties.get('ports', [])
|
||||
auth_enabled = netdisk_properties.get('auth_enabled')
|
||||
if (conf.source_protocol == 'rbd' and
|
||||
CONF.libvirt.rbd_secret_uuid):
|
||||
conf.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid
|
||||
auth_enabled = True # Force authentication locally
|
||||
if CONF.libvirt.rbd_user:
|
||||
conf.auth_username = CONF.libvirt.rbd_user
|
||||
if conf.source_protocol == 'iscsi':
|
||||
try:
|
||||
conf.source_name = ("%(target_iqn)s/%(target_lun)s" %
|
||||
netdisk_properties)
|
||||
target_portal = netdisk_properties['target_portal']
|
||||
except KeyError:
|
||||
raise exception.NovaException(_("Invalid volume source data"))
|
||||
|
||||
ip, port = utils.parse_server_string(target_portal)
|
||||
if ip == '' or port == '':
|
||||
raise exception.NovaException(_("Invalid target_lun"))
|
||||
conf.source_hosts = [ip]
|
||||
conf.source_ports = [port]
|
||||
if netdisk_properties.get('auth_method') == 'CHAP':
|
||||
auth_enabled = True
|
||||
conf.auth_secret_type = 'iscsi'
|
||||
password = netdisk_properties.get('auth_password')
|
||||
conf.auth_secret_uuid = self._get_secret_uuid(conf, password)
|
||||
if auth_enabled:
|
||||
conf.auth_username = (conf.auth_username or
|
||||
netdisk_properties['auth_username'])
|
||||
conf.auth_secret_type = (conf.auth_secret_type or
|
||||
netdisk_properties['secret_type'])
|
||||
conf.auth_secret_uuid = (conf.auth_secret_uuid or
|
||||
netdisk_properties['secret_uuid'])
|
||||
return conf
|
||||
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
"""Detach the volume from instance_name."""
|
||||
super(LibvirtNetVolumeDriver,
|
||||
self).disconnect_volume(connection_info, disk_dev)
|
||||
self._delete_secret_by_name(connection_info)
|
@ -22,7 +22,6 @@ from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.i18n import _LE
|
||||
from nova.i18n import _LW
|
||||
from nova import utils
|
||||
@ -35,11 +34,6 @@ volume_opts = [
|
||||
cfg.IntOpt('num_iscsi_scan_tries',
|
||||
default=5,
|
||||
help='Number of times to rescan iSCSI target to find volume'),
|
||||
cfg.StrOpt('rbd_user',
|
||||
help='The RADOS client name for accessing rbd volumes'),
|
||||
cfg.StrOpt('rbd_secret_uuid',
|
||||
help='The libvirt UUID of the secret for the rbd_user'
|
||||
'volumes'),
|
||||
cfg.BoolOpt('iscsi_use_multipath',
|
||||
default=False,
|
||||
help='Use multipath connection of the iSCSI volume'),
|
||||
@ -125,26 +119,6 @@ class LibvirtBaseVolumeDriver(object):
|
||||
|
||||
return conf
|
||||
|
||||
def _get_secret_uuid(self, conf, password=None):
|
||||
secret = self.connection._host.find_secret(conf.source_protocol,
|
||||
conf.source_name)
|
||||
if secret is None:
|
||||
secret = self.connection._host.create_secret(conf.source_protocol,
|
||||
conf.source_name,
|
||||
password)
|
||||
return secret.UUIDString()
|
||||
|
||||
def _delete_secret_by_name(self, connection_info):
|
||||
source_protocol = connection_info['driver_volume_type']
|
||||
netdisk_properties = connection_info['data']
|
||||
if source_protocol == 'rbd':
|
||||
return
|
||||
elif source_protocol == 'iscsi':
|
||||
usage_type = 'iscsi'
|
||||
usage_name = ("%(target_iqn)s/%(target_lun)s" %
|
||||
netdisk_properties)
|
||||
self.connection._host.delete_secret(usage_type, usage_name)
|
||||
|
||||
def connect_volume(self, connection_info, disk_info):
|
||||
"""Connect the volume. Returns xml for libvirt."""
|
||||
pass
|
||||
@ -185,64 +159,6 @@ class LibvirtFakeVolumeDriver(LibvirtBaseVolumeDriver):
|
||||
return conf
|
||||
|
||||
|
||||
class LibvirtNetVolumeDriver(LibvirtBaseVolumeDriver):
|
||||
"""Driver to attach Network volumes to libvirt."""
|
||||
def __init__(self, connection):
|
||||
super(LibvirtNetVolumeDriver,
|
||||
self).__init__(connection, is_block_dev=False)
|
||||
|
||||
def get_config(self, connection_info, disk_info):
|
||||
"""Returns xml for libvirt."""
|
||||
conf = super(LibvirtNetVolumeDriver,
|
||||
self).get_config(connection_info, disk_info)
|
||||
|
||||
netdisk_properties = connection_info['data']
|
||||
conf.source_type = "network"
|
||||
conf.source_protocol = connection_info['driver_volume_type']
|
||||
conf.source_name = netdisk_properties.get('name')
|
||||
conf.source_hosts = netdisk_properties.get('hosts', [])
|
||||
conf.source_ports = netdisk_properties.get('ports', [])
|
||||
auth_enabled = netdisk_properties.get('auth_enabled')
|
||||
if (conf.source_protocol == 'rbd' and
|
||||
CONF.libvirt.rbd_secret_uuid):
|
||||
conf.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid
|
||||
auth_enabled = True # Force authentication locally
|
||||
if CONF.libvirt.rbd_user:
|
||||
conf.auth_username = CONF.libvirt.rbd_user
|
||||
if conf.source_protocol == 'iscsi':
|
||||
try:
|
||||
conf.source_name = ("%(target_iqn)s/%(target_lun)s" %
|
||||
netdisk_properties)
|
||||
target_portal = netdisk_properties['target_portal']
|
||||
except KeyError:
|
||||
raise exception.NovaException(_("Invalid volume source data"))
|
||||
|
||||
ip, port = utils.parse_server_string(target_portal)
|
||||
if ip == '' or port == '':
|
||||
raise exception.NovaException(_("Invalid target_lun"))
|
||||
conf.source_hosts = [ip]
|
||||
conf.source_ports = [port]
|
||||
if netdisk_properties.get('auth_method') == 'CHAP':
|
||||
auth_enabled = True
|
||||
conf.auth_secret_type = 'iscsi'
|
||||
password = netdisk_properties.get('auth_password')
|
||||
conf.auth_secret_uuid = self._get_secret_uuid(conf, password)
|
||||
if auth_enabled:
|
||||
conf.auth_username = (conf.auth_username or
|
||||
netdisk_properties['auth_username'])
|
||||
conf.auth_secret_type = (conf.auth_secret_type or
|
||||
netdisk_properties['secret_type'])
|
||||
conf.auth_secret_uuid = (conf.auth_secret_uuid or
|
||||
netdisk_properties['secret_uuid'])
|
||||
return conf
|
||||
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
"""Detach the volume from instance_name."""
|
||||
super(LibvirtNetVolumeDriver,
|
||||
self).disconnect_volume(connection_info, disk_dev)
|
||||
self._delete_secret_by_name(connection_info)
|
||||
|
||||
|
||||
class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
|
||||
"""Driver to attach Network volumes to libvirt."""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user