RBD: consider a custom keyring in connection info
If a 'keyring' key is found in the connection info passed to connect_volume() use its value as the path to the keyring instead of the default location (/etc/ceph/<cluster>.client.<user>.keyring). This allows services such as cinder's RBD and Ceph backup drivers to make use of a custom keyring path that an admin has defined. Change-Id: Ib1230d3e40f56371567e1aead40db59667bad295 Closes-bug: #1668304
This commit is contained in:
parent
57f6eb74e7
commit
7b9a6686bc
@ -70,14 +70,19 @@ class RBDConnector(base.BaseLinuxConnector):
|
|||||||
return list(map(_sanitize_host, hosts))
|
return list(map(_sanitize_host, hosts))
|
||||||
|
|
||||||
def _create_ceph_conf(self, monitor_ips, monitor_ports,
|
def _create_ceph_conf(self, monitor_ips, monitor_ports,
|
||||||
cluster_name, user):
|
cluster_name, user, keyring_path):
|
||||||
monitors = ["%s:%s" % (ip, port) for ip, port in
|
monitors = ["%s:%s" % (ip, port) for ip, port in
|
||||||
zip(self._sanitize_mon_hosts(monitor_ips), monitor_ports)]
|
zip(self._sanitize_mon_hosts(monitor_ips), monitor_ports)]
|
||||||
mon_hosts = "mon_host = %s" % (','.join(monitors))
|
mon_hosts = "mon_host = %s" % (','.join(monitors))
|
||||||
|
|
||||||
client_section = "[client.%s]" % user
|
client_section = "[client.%s]" % user
|
||||||
keyring = ("keyring = /etc/ceph/%s.client.%s.keyring" %
|
|
||||||
(cluster_name, user))
|
if keyring_path is None:
|
||||||
|
keyring = ("keyring = /etc/ceph/%s.client.%s.keyring" %
|
||||||
|
(cluster_name, user))
|
||||||
|
else:
|
||||||
|
keyring = "keyring = %s" % keyring_path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fd, ceph_conf_path = tempfile.mkstemp(prefix="brickrbd_")
|
fd, ceph_conf_path = tempfile.mkstemp(prefix="brickrbd_")
|
||||||
with os.fdopen(fd, 'w') as conf_file:
|
with os.fdopen(fd, 'w') as conf_file:
|
||||||
@ -95,12 +100,14 @@ class RBDConnector(base.BaseLinuxConnector):
|
|||||||
cluster_name = connection_properties.get('cluster_name')
|
cluster_name = connection_properties.get('cluster_name')
|
||||||
monitor_ips = connection_properties.get('hosts')
|
monitor_ips = connection_properties.get('hosts')
|
||||||
monitor_ports = connection_properties.get('ports')
|
monitor_ports = connection_properties.get('ports')
|
||||||
|
keyring_path = connection_properties.get('keyring')
|
||||||
except IndexError:
|
except IndexError:
|
||||||
msg = _("Connect volume failed, malformed connection properties")
|
msg = _("Connect volume failed, malformed connection properties")
|
||||||
raise exception.BrickException(msg=msg)
|
raise exception.BrickException(msg=msg)
|
||||||
|
|
||||||
conf = self._create_ceph_conf(monitor_ips, monitor_ports,
|
conf = self._create_ceph_conf(monitor_ips, monitor_ports,
|
||||||
str(cluster_name), user)
|
str(cluster_name), user,
|
||||||
|
keyring_path)
|
||||||
try:
|
try:
|
||||||
rbd_client = linuxrbd.RBDClient(user, pool, conffile=conf,
|
rbd_client = linuxrbd.RBDClient(user, pool, conffile=conf,
|
||||||
rbd_cluster_name=str(cluster_name))
|
rbd_cluster_name=str(cluster_name))
|
||||||
|
@ -94,6 +94,21 @@ class RBDConnectorTestCase(test_connector.ConnectorTestCase):
|
|||||||
self.assertIsInstance(device_info['path'],
|
self.assertIsInstance(device_info['path'],
|
||||||
linuxrbd.RBDVolumeIOWrapper)
|
linuxrbd.RBDVolumeIOWrapper)
|
||||||
|
|
||||||
|
@mock.patch('os_brick.initiator.linuxrbd.rbd')
|
||||||
|
@mock.patch('os_brick.initiator.linuxrbd.rados')
|
||||||
|
@mock.patch.object(rbd.RBDConnector, '_create_ceph_conf')
|
||||||
|
@mock.patch('os.path.exists')
|
||||||
|
def test_custom_keyring(self, mock_path, mock_conf, mock_rados, mock_rbd):
|
||||||
|
conn = rbd.RBDConnector(None)
|
||||||
|
mock_path.return_value = False
|
||||||
|
mock_conf.return_value = "/tmp/fake_dir/fake_ceph.conf"
|
||||||
|
custom_keyring_path = "/foo/bar/baz"
|
||||||
|
self.connection_properties['keyring'] = custom_keyring_path
|
||||||
|
conn.connect_volume(self.connection_properties)
|
||||||
|
mock_conf.assert_called_once_with(self.hosts, self.ports,
|
||||||
|
self.clustername, self.user,
|
||||||
|
custom_keyring_path)
|
||||||
|
|
||||||
@ddt.data((['192.168.1.1', '192.168.1.2'],
|
@ddt.data((['192.168.1.1', '192.168.1.2'],
|
||||||
['192.168.1.1', '192.168.1.2']),
|
['192.168.1.1', '192.168.1.2']),
|
||||||
(['3ffe:1900:4545:3:200:f8ff:fe21:67cf',
|
(['3ffe:1900:4545:3:200:f8ff:fe21:67cf',
|
||||||
@ -122,7 +137,7 @@ class RBDConnectorTestCase(test_connector.ConnectorTestCase):
|
|||||||
with mock.patch('os.fdopen', mockopen, create=True):
|
with mock.patch('os.fdopen', mockopen, create=True):
|
||||||
rbd_connector = rbd.RBDConnector(None)
|
rbd_connector = rbd.RBDConnector(None)
|
||||||
conf_path = rbd_connector._create_ceph_conf(
|
conf_path = rbd_connector._create_ceph_conf(
|
||||||
self.hosts, self.ports, self.clustername, self.user)
|
self.hosts, self.ports, self.clustername, self.user, None)
|
||||||
self.assertEqual(conf_path, tmpfile)
|
self.assertEqual(conf_path, tmpfile)
|
||||||
mock_mkstemp.assert_called_once_with(prefix='brickrbd_')
|
mock_mkstemp.assert_called_once_with(prefix='brickrbd_')
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- Add support to use custom Ceph keyring files (previously os-brick
|
||||||
|
hardcoded using /etc/ceph/<cluster>.client.<user>.keyring file).
|
Loading…
Reference in New Issue
Block a user