RBD: enclose ipv6 addresses in square brackets
When using ipv6, the IP address must be enclosed in square brackets
according to RFC 3986, Section 3.2.2. Without this, an ipv6 cloud will
fail to connect to the ceph cluster prior to backup because the address
and port are not parsed correctly.
Closes-Bug: #1640914
Change-Id: I6501c7cdac38fe545d12e786448a8e0c0a4f6a25
(cherry picked from commit f3db22f57a
)
This commit is contained in:
parent
376638513d
commit
3766c65c43
|
@ -18,6 +18,7 @@ import tempfile
|
|||
|
||||
from oslo_concurrency import processutils as putils
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import netutils
|
||||
|
||||
from os_brick.i18n import _, _LE
|
||||
from os_brick import exception
|
||||
|
@ -60,16 +61,24 @@ class RBDConnector(base.BaseLinuxConnector):
|
|||
# TODO(e0ne): Implement this for local volume.
|
||||
return []
|
||||
|
||||
def _sanitize_mon_hosts(self, hosts):
|
||||
def _sanitize_host(host):
|
||||
if netutils.is_valid_ipv6(host):
|
||||
host = '[%s]' % host
|
||||
return host
|
||||
return list(map(_sanitize_host, hosts))
|
||||
|
||||
def _create_ceph_conf(self, monitor_ips, monitor_ports,
|
||||
cluster_name, user):
|
||||
monitors = ["%s:%s" % (ip, port) for ip, port in
|
||||
zip(self._sanitize_mon_hosts(monitor_ips), monitor_ports)]
|
||||
mon_hosts = "mon_host = %s" % (','.join(monitors))
|
||||
|
||||
client_section = "[client.%s]" % user
|
||||
keyring = ("keyring = /etc/ceph/%s.client.%s.keyring" %
|
||||
(cluster_name, user))
|
||||
try:
|
||||
fd, ceph_conf_path = tempfile.mkstemp()
|
||||
monitors = ["%s:%s" % (ip, port) for ip, port
|
||||
in zip(monitor_ips, monitor_ports)]
|
||||
mon_hosts = "mon_host = %s" % (','.join(monitors))
|
||||
client_section = "[client.%s]" % user
|
||||
keyring = ("keyring = /etc/ceph/%s.client.%s.keyring" %
|
||||
(cluster_name, user))
|
||||
with os.fdopen(fd, 'w') as conf_file:
|
||||
conf_file.writelines([mon_hosts, "\n",
|
||||
client_section, "\n", keyring])
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
# 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 ddt
|
||||
import mock
|
||||
|
||||
from os_brick.initiator.connectors import rbd
|
||||
|
@ -20,6 +21,7 @@ from os_brick.tests.initiator import test_connector
|
|||
from os_brick import utils
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class RBDConnectorTestCase(test_connector.ConnectorTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -92,6 +94,24 @@ class RBDConnectorTestCase(test_connector.ConnectorTestCase):
|
|||
self.assertTrue(isinstance(device_info['path'],
|
||||
linuxrbd.RBDVolumeIOWrapper))
|
||||
|
||||
@ddt.data((['192.168.1.1', '192.168.1.2'],
|
||||
['192.168.1.1', '192.168.1.2']),
|
||||
(['3ffe:1900:4545:3:200:f8ff:fe21:67cf',
|
||||
'fe80:0:0:0:200:f8ff:fe21:67cf'],
|
||||
['[3ffe:1900:4545:3:200:f8ff:fe21:67cf]',
|
||||
'[fe80:0:0:0:200:f8ff:fe21:67cf]']),
|
||||
(['foobar', 'fizzbuzz'], ['foobar', 'fizzbuzz']),
|
||||
(['192.168.1.1',
|
||||
'3ffe:1900:4545:3:200:f8ff:fe21:67cf',
|
||||
'hello, world!'],
|
||||
['192.168.1.1',
|
||||
'[3ffe:1900:4545:3:200:f8ff:fe21:67cf]',
|
||||
'hello, world!']))
|
||||
@ddt.unpack
|
||||
def test_sanitize_mon_host(self, hosts_in, hosts_out):
|
||||
conn = rbd.RBDConnector(None)
|
||||
self.assertEqual(hosts_out, conn._sanitize_mon_hosts(hosts_in))
|
||||
|
||||
@mock.patch('os_brick.initiator.connectors.rbd.tempfile.mkstemp')
|
||||
def test_create_ceph_conf(self, mock_mkstemp):
|
||||
mockopen = mock.mock_open()
|
||||
|
|
Loading…
Reference in New Issue