Pure Storage FlashArray iSCSI driver target CIDR support

Add new configuration parameter to allow user to specify
the CIDR of iSCSI targets on a FlashArray that can be
connected to.
This allows a FlashArray to have targets in multiple VLANs
and Cinder not try to connect to inaccesible targets which
can cause serious timeouts when connecting Cinder volumes
to hosts.
Default setting will be 0.0.0.0/0 which allow connection
to any live iSCSI target.

Change-Id: Ic813445cb5d55edb68ca8e756b9350ca7e8a1270
This commit is contained in:
Simon Dodsley 2019-05-14 18:01:44 -04:00
parent 22e09a4bf3
commit 23cfc6efab
3 changed files with 36 additions and 3 deletions

View File

@ -76,6 +76,7 @@ ISCSI_PORT_NAMES = ["ct0.eth2", "ct0.eth3", "ct1.eth2", "ct1.eth3"]
FC_PORT_NAMES = ["ct0.fc2", "ct0.fc3", "ct1.fc2", "ct1.fc3"]
ISCSI_IPS = ["10.0.0." + str(i + 1) for i in range(len(ISCSI_PORT_NAMES))]
AC_ISCSI_IPS = ["10.1.1." + str(i + 1) for i in range(len(ISCSI_PORT_NAMES))]
ISCSI_CIDR = "0.0.0.0/0"
FC_WWNS = ["21000024ff59fe9" + str(i + 1) for i in range(len(FC_PORT_NAMES))]
AC_FC_WWNS = [
"21000024ff59fab" + str(i + 1) for i in range(len(FC_PORT_NAMES))]
@ -489,6 +490,7 @@ class PureDriverTestCase(test.TestCase):
self.mock_config.pure_eradicate_on_delete = False
self.mock_config.driver_ssl_cert_verify = False
self.mock_config.driver_ssl_cert_path = None
self.mock_config.pure_iscsi_cidr = ISCSI_CIDR
self.array = mock.Mock()
self.array.get.return_value = GET_ARRAY_PRIMARY
self.array.array_name = GET_ARRAY_PRIMARY["array_name"]

View File

@ -19,6 +19,7 @@ This driver requires Purity version 4.0.0 or later.
"""
import functools
import ipaddress
import math
import platform
import re
@ -83,6 +84,10 @@ PURE_OPTS = [
cfg.StrOpt("pure_replication_pod_name", default="cinder-pod",
help="Pure Pod name to use for sync replication "
"(will be created if it does not exist)."),
cfg.StrOpt("pure_iscsi_cidr", default="0.0.0.0/0",
help="CIDR of FlashArray iSCSI targets hosts are allowed to "
"connect to. Default will allow connection to any "
"IP address."),
cfg.BoolOpt("pure_eradicate_on_delete",
default=False,
help="When enabled, all Pure volumes, snapshots, and "
@ -2323,7 +2328,7 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver):
the underlying storage connectivity with the FlashArray.
"""
VERSION = "8.0.0"
VERSION = "9.0.0"
def __init__(self, *args, **kwargs):
execute = kwargs.pop("execute", utils.execute)
@ -2391,6 +2396,7 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver):
target_luns = []
target_iqns = []
target_portals = []
valid_portals = []
# Aggregate all targets together, we may end up with different LUNs
# for different target iqn/portal sets (ie. it could be a unique LUN
@ -2402,11 +2408,29 @@ class PureISCSIDriver(PureBaseVolumeDriver, san.SanISCSIDriver):
target_iqns.append(port["iqn"])
target_portals.append(port["portal"])
# Check to ensure all returned portal IP addresses
# are in iSCSI target CIDR
if not isinstance(self.configuration.pure_iscsi_cidr, six.text_type):
cidr = self.configuration.pure_iscsi_cidr.decode('utf8')
else:
cidr = self.configuration.pure_iscsi_cidr
check_cidr = ipaddress.IPv4Network(cidr)
for target_portal in target_portals:
if not isinstance(target_portal.split(":")[0], six.text_type):
portal = (target_portal.split(":")[0]).decode('utf8')
else:
portal = target_portal.split(":")[0]
check_ip = ipaddress.IPv4Address(portal)
if check_ip in check_cidr:
valid_portals.append(target_portal)
LOG.info("iSCSI target portals that match CIDR range: '%s'",
valid_portals)
# If we have multiple ports always report them.
if target_luns and target_iqns and target_portals:
if target_luns and target_iqns and valid_portals:
props["data"]["target_luns"] = target_luns
props["data"]["target_iqns"] = target_iqns
props["data"]["target_portals"] = target_portals
props["data"]["target_portals"] = valid_portals
return props

View File

@ -0,0 +1,7 @@
---
features:
- |
Pure Storage FlashArray driver has added configuration option
``pure_iscsi_cidr`` for setting a network CIDR for iSCSI target
connection. The default value will allow connections to all
iSCSI targets.