Add custom keyring when initializing RBD connection
Added RBD keyring configuration parameter which will help administrator set an custom keyring path to the Ceph cluster. Closes-bug: #1668304 Change-Id: I263cc10dc877b20bbc205ea55173ad3878687ea1
This commit is contained in:
parent
ffe7d919d8
commit
d0520a07e9
@ -155,6 +155,7 @@ class RBDTestCase(test.TestCase):
|
||||
self.cfg.rbd_cluster_name = 'nondefault'
|
||||
self.cfg.rbd_pool = 'rbd'
|
||||
self.cfg.rbd_ceph_conf = '/etc/ceph/my_ceph.conf'
|
||||
self.cfg.rbd_keyring_conf = '/etc/ceph/my_ceph.client.keyring'
|
||||
self.cfg.rbd_secret_uuid = None
|
||||
self.cfg.rbd_user = 'cinder'
|
||||
self.cfg.volume_backend_name = None
|
||||
@ -1149,13 +1150,23 @@ class RBDTestCase(test.TestCase):
|
||||
self.assertEqual((hosts, ports), self.driver._get_mon_addrs())
|
||||
|
||||
@common_mocks
|
||||
def test_initialize_connection(self):
|
||||
hosts = ['::1', '::1', '::1', '127.0.0.1', 'example.com']
|
||||
ports = ['6789', '6790', '6791', '6792', '6791']
|
||||
def _initialize_connection_helper(self, expected, hosts, ports):
|
||||
|
||||
with mock.patch.object(self.driver, '_get_mon_addrs') as \
|
||||
mock_get_mon_addrs:
|
||||
mock_get_mon_addrs.return_value = (hosts, ports)
|
||||
actual = self.driver.initialize_connection(self.volume_a, None)
|
||||
self.assertDictEqual(expected, actual)
|
||||
self.assertTrue(mock_get_mon_addrs.called)
|
||||
|
||||
@mock.patch.object(cinder.volume.drivers.rbd.RBDDriver,
|
||||
'_get_keyring_contents')
|
||||
def test_initialize_connection(self, mock_keyring):
|
||||
hosts = ['::1', '::1', '::1', '127.0.0.1', 'example.com']
|
||||
ports = ['6789', '6790', '6791', '6792', '6791']
|
||||
|
||||
keyring_data = "[client.cinder]\n key = test\n"
|
||||
mock_keyring.return_value = keyring_data
|
||||
|
||||
expected = {
|
||||
'driver_volume_type': 'rbd',
|
||||
@ -1171,11 +1182,39 @@ class RBDTestCase(test.TestCase):
|
||||
'secret_uuid': None,
|
||||
'volume_id': self.volume_a.id,
|
||||
'discard': True,
|
||||
'keyring': keyring_data,
|
||||
}
|
||||
}
|
||||
actual = self.driver.initialize_connection(self.volume_a, None)
|
||||
self.assertDictEqual(expected, actual)
|
||||
self.assertTrue(mock_get_mon_addrs.called)
|
||||
self._initialize_connection_helper(expected, hosts, ports)
|
||||
|
||||
# Check how it will work with empty keyring path
|
||||
mock_keyring.return_value = None
|
||||
expected['data']['keyring'] = None
|
||||
self._initialize_connection_helper(expected, hosts, ports)
|
||||
|
||||
def test__get_keyring_contents_no_config_file(self):
|
||||
self.cfg.rbd_keyring_conf = ''
|
||||
self.assertIsNone(self.driver._get_keyring_contents())
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
def test__get_keyring_contents_read_file(self, mock_isfile):
|
||||
mock_isfile.return_value = True
|
||||
keyring_data = "[client.cinder]\n key = test\n"
|
||||
mockopen = mock.mock_open(read_data=keyring_data)
|
||||
mockopen.return_value.__exit__ = mock.Mock()
|
||||
with mock.patch('cinder.volume.drivers.rbd.open', mockopen,
|
||||
create=True):
|
||||
self.assertEqual(self.driver._get_keyring_contents(), keyring_data)
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
def test__get_keyring_contents_raise_error(self, mock_isfile):
|
||||
mock_isfile.return_value = True
|
||||
mockopen = mock.mock_open()
|
||||
mockopen.return_value.__exit__ = mock.Mock()
|
||||
with mock.patch('cinder.volume.drivers.rbd.open', mockopen,
|
||||
create=True) as mock_keyring_file:
|
||||
mock_keyring_file.side_effect = IOError
|
||||
self.assertIsNone(self.driver._get_keyring_contents())
|
||||
|
||||
@ddt.data({'rbd_chunk_size': 1, 'order': 20},
|
||||
{'rbd_chunk_size': 8, 'order': 23},
|
||||
|
@ -59,6 +59,9 @@ RBD_OPTS = [
|
||||
cfg.StrOpt('rbd_ceph_conf',
|
||||
default='', # default determined by librados
|
||||
help='Path to the ceph configuration file'),
|
||||
cfg.StrOpt('rbd_keyring_conf',
|
||||
default='',
|
||||
help='Path to the ceph keyring file'),
|
||||
cfg.BoolOpt('rbd_flatten_volume_from_snapshot',
|
||||
default=False,
|
||||
help='Flatten volumes created from snapshots to remove '
|
||||
@ -1023,6 +1026,20 @@ class RBDDriver(driver.CloneableImageVD,
|
||||
"""Removes an export for a logical volume."""
|
||||
pass
|
||||
|
||||
def _get_keyring_contents(self):
|
||||
# NOTE(danpawlik) If keyring is not provided in Cinder configuration,
|
||||
# os-brick library will take keyring from default path.
|
||||
keyring_file = self.configuration.rbd_keyring_conf
|
||||
keyring_data = None
|
||||
try:
|
||||
if os.path.isfile(keyring_file):
|
||||
with open(keyring_file, 'r') as k_file:
|
||||
keyring_data = k_file.read()
|
||||
except IOError:
|
||||
LOG.debug('Cannot read RBD keyring file: %s.', keyring_file)
|
||||
|
||||
return keyring_data
|
||||
|
||||
def initialize_connection(self, volume, connector):
|
||||
hosts, ports = self._get_mon_addrs()
|
||||
data = {
|
||||
@ -1039,6 +1056,7 @@ class RBDDriver(driver.CloneableImageVD,
|
||||
'secret_uuid': self.configuration.rbd_secret_uuid,
|
||||
'volume_id': volume.id,
|
||||
"discard": True,
|
||||
'keyring': self._get_keyring_contents(),
|
||||
}
|
||||
}
|
||||
LOG.debug('connection data: %s', data)
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added RBD keyring configuration parameter ``rbd_keyring_conf`` to define
|
||||
custom path of Ceph keyring file.
|
Loading…
Reference in New Issue
Block a user