From fddb9b7962ab2d4f3b6f57faef1c090b097b60c6 Mon Sep 17 00:00:00 2001 From: Gorka Eguileor Date: Tue, 20 Aug 2019 19:36:09 +0200 Subject: [PATCH] Fix LVM IPv6 target portals The LVM driver is reporting incorrect target_portal and target_portals entries for IPv6 with all the targets, as it is not enclosing the address in square brackets making it impossible for iscsiadm in OS-Brick to tell the port appart from the IP address. This patch makes sure that IPv6 addresses in target_portal and target_portals are properly formatted in the [IPv6_address]:port when the IPv6_address does not already include the square brackets. This fix affects all the targets: IET, LIO, TGT, CXT, and SCST. Closes-Bug: #1696866 Change-Id: Ie7053c813af8c99b5545222d4724b71061348a09 --- .../unit/targets/test_base_iscsi_driver.py | 17 +++++++++++++++++ cinder/tests/unit/targets/test_scst_driver.py | 13 +++++++++++++ cinder/volume/targets/iscsi.py | 3 ++- cinder/volume/targets/scst.py | 3 ++- cinder/volume/utils.py | 8 ++++++++ .../notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml | 5 +++++ 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml diff --git a/cinder/tests/unit/targets/test_base_iscsi_driver.py b/cinder/tests/unit/targets/test_base_iscsi_driver.py index a9ea65812b3..0fdcb4e9893 100644 --- a/cinder/tests/unit/targets/test_base_iscsi_driver.py +++ b/cinder/tests/unit/targets/test_base_iscsi_driver.py @@ -158,6 +158,23 @@ class TestBaseISCSITargetDriver(tf.TargetDriverFixture): ['portal2']) self.assertEqual('portal:3260;portal2:3260,1 target 2', location) + def test_iscsi_location_IPv6(self): + ip = 'fd00:fd00:fd00:3000::12' + ip2 = 'fd00:fd00:fd00:3000::13' + + location = self.target._iscsi_location(ip, 1, 'target', 2) + self.assertEqual('[%s]:3260,1 target 2' % ip, location) + + location = self.target._iscsi_location(ip, 1, 'target', 2, [ip2]) + self.assertEqual('[%s]:3260;[%s]:3260,1 target 2' % (ip, ip2), + location) + + # Mix of IPv6 (already with square brackets) and IPv4 + ip = '[' + ip + ']' + location = self.target._iscsi_location(ip, 1, 'target', 2, + ['192.168.1.1']) + self.assertEqual(ip + ':3260;192.168.1.1:3260,1 target 2', location) + def test_get_target_chap_auth(self): ctxt = context.get_admin_context() self.assertEqual(('otzL', '234Z'), diff --git a/cinder/tests/unit/targets/test_scst_driver.py b/cinder/tests/unit/targets/test_scst_driver.py index 067b0d5f37f..1e879d4fb39 100644 --- a/cinder/tests/unit/targets/test_scst_driver.py +++ b/cinder/tests/unit/targets/test_scst_driver.py @@ -231,3 +231,16 @@ class TestSCSTAdmDriver(tf.TargetDriverFixture): 'iqn.2010-10.org.openstack:testvol', 'ed2c2222-5fc0-11e4-aa15-123b93f75cba', 0, 1, self.fake_volumes_dir, None) + + def test_iscsi_location(self): + location = self.target._iscsi_location('portal', 1, 'target', 2) + self.assertEqual('portal:3260,1 target 2', location) + + def test_iscsi_location_IPv6(self): + ip = 'fd00:fd00:fd00:3000::12' + location = self.target._iscsi_location(ip, 1, 'target', 2) + self.assertEqual('[%s]:3260,1 target 2' % ip, location) + + ip = '[' + ip + ']' + location = self.target._iscsi_location(ip, 1, 'target', 2) + self.assertEqual(ip + ':3260,1 target 2', location) diff --git a/cinder/volume/targets/iscsi.py b/cinder/volume/targets/iscsi.py index 67311aadbfa..03bf7ef7d54 100644 --- a/cinder/volume/targets/iscsi.py +++ b/cinder/volume/targets/iscsi.py @@ -300,7 +300,8 @@ class ISCSITarget(driver.Target): def _iscsi_location(self, ip, target, iqn, lun=None, ip_secondary=None): ip_secondary = ip_secondary or [] port = self.configuration.target_port - portals = map(lambda x: "%s:%s" % (x, port), [ip] + ip_secondary) + portals = map(lambda x: "%s:%s" % (vutils.sanitize_host(x), port), + [ip] + ip_secondary) return ("%(portals)s,%(target)s %(iqn)s %(lun)s" % ({'portals': ";".join(portals), 'target': target, 'iqn': iqn, 'lun': lun})) diff --git a/cinder/volume/targets/scst.py b/cinder/volume/targets/scst.py index 3d6c2234a2a..dcd7833f4dd 100644 --- a/cinder/volume/targets/scst.py +++ b/cinder/volume/targets/scst.py @@ -231,7 +231,8 @@ class SCSTAdm(iscsi.ISCSITarget): return tid def _iscsi_location(self, ip, target, iqn, lun=None): - return "%s:%s,%s %s %s" % (ip, self.configuration.target_port, + return "%s:%s,%s %s %s" % (vutils.sanitize_host(ip), + self.configuration.target_port, target, iqn, lun) def _get_iscsi_name(self, volume): diff --git a/cinder/volume/utils.py b/cinder/volume/utils.py index 166d81cf00a..19df5de56bc 100644 --- a/cinder/volume/utils.py +++ b/cinder/volume/utils.py @@ -38,6 +38,7 @@ from oslo_concurrency import processutils from oslo_config import cfg from oslo_log import log as logging from oslo_utils import excutils +from oslo_utils import netutils from oslo_utils import strutils from oslo_utils import timeutils from oslo_utils import units @@ -1205,3 +1206,10 @@ def check_encryption_provider(db, volume, context): raise exception.VolumeDriverException(message=msg) return encryption + + +def sanitize_host(host): + """Ensure IPv6 addresses are enclosed in [] for iSCSI portals.""" + if netutils.is_valid_ipv6(host): + return '[%s]' % host + return host diff --git a/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml b/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml new file mode 100644 index 00000000000..dc38fef6d31 --- /dev/null +++ b/releasenotes/notes/lvm-ipv6-fix-e8d418726c92bbd5.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + LVM iSCSI driver fix for IPv6 addresses for the different targets, IET, + LIO, TGT, CXT, and SCST.