Modify Pure driver to configure PG/Pod names

Add two config options to the Pure Storage driver to allow setting the
names for replication PGs and Pods. This is beneficial in multi-backend
scenarios so that each backend can use a different PG/Pod. It also
allows for the use of existing PGs/Pods.

These options should not be modified after volumes exist on a backend.

Change-Id: Ie0dbf00fb2ecea3344e58d2b84fd4dfd6ae1daee
This commit is contained in:
Avishay Traeger 2018-08-27 09:09:55 +03:00
parent 45df029a4d
commit 030d893697
4 changed files with 62 additions and 14 deletions

View File

@ -538,6 +538,8 @@ class PureBaseSharedDriverTestCase(PureDriverTestCase):
super(PureBaseSharedDriverTestCase, self).setUp()
self.driver = pure.PureBaseVolumeDriver(configuration=self.mock_config)
self.driver._array = self.array
self.driver._replication_pod_name = 'cinder-pod'
self.driver._replication_pg_name = 'cinder-group'
self.array.get_rest_version.return_value = '1.4'
self.purestorage_module.FlashArray.side_effect = None
self.async_array2.get_rest_version.return_value = '1.4'
@ -603,6 +605,9 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase):
REPLICATION_RETENTION_LONG_TERM)
self.mock_config.pure_replica_retention_long_term_default = (
REPLICATION_RETENTION_LONG_TERM_PER_DAY)
self.mock_config.pure_replication_pg_name = 'cinder-group'
self.mock_config.pure_replication_pod_name = 'cinder-pod'
self.mock_config.safe_get.return_value = [
{"backend_id": self.driver._array.array_id,
"managed_backend_name": None,
@ -2455,12 +2460,12 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase):
self.assertEqual(expected_model_update, model_update)
if expected_add_to_group:
self.array.set_pgroup.assert_called_once_with(
pure.REPLICATION_CG_NAME,
self.driver._replication_pg_name,
addvollist=[vol_name]
)
if expected_remove_from_pgroup:
self.array.set_pgroup.assert_called_once_with(
pure.REPLICATION_CG_NAME,
self.driver._replication_pg_name,
remvollist=[vol_name]
)

View File

@ -72,6 +72,12 @@ PURE_OPTS = [
cfg.IntOpt("pure_replica_retention_long_term_default", default=7,
help="Retain snapshots per day on target for this time "
"(in days.)"),
cfg.StrOpt("pure_replication_pg_name", default="cinder-group",
help="Pure Protection Group name to use for async replication "
"(will be created if it does not exist)."),
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.BoolOpt("pure_eradicate_on_delete",
default=False,
help="When enabled, all Pure volumes, snapshots, and "
@ -89,8 +95,6 @@ CONF.register_opts(PURE_OPTS, group=configuration.SHARED_CONF_GROUP)
INVALID_CHARACTERS = re.compile(r"[^-a-zA-Z0-9]")
GENERATED_NAME = re.compile(r".*-[a-f0-9]{32}-cinder$")
REPLICATION_CG_NAME = "cinder-group"
REPLICATION_POD_NAME = "cinder-pod"
REPLICATION_TYPE_SYNC = "sync"
REPLICATION_TYPE_ASYNC = "async"
REPLICATION_TYPES = [REPLICATION_TYPE_SYNC, REPLICATION_TYPE_ASYNC]
@ -181,8 +185,8 @@ class PureBaseVolumeDriver(san.SanDriver):
self._replication_target_arrays = []
self._active_cluster_target_arrays = []
self._uniform_active_cluster_target_arrays = []
self._replication_pg_name = REPLICATION_CG_NAME
self._replication_pod_name = REPLICATION_POD_NAME
self._replication_pg_name = None
self._replication_pod_name = None
self._replication_interval = None
self._replication_retention_short_term = None
self._replication_retention_long_term = None
@ -200,6 +204,10 @@ class PureBaseVolumeDriver(san.SanDriver):
}
def parse_replication_configs(self):
self._replication_pg_name = (
self.configuration.pure_replication_pg_name)
self._replication_pod_name = (
self.configuration.pure_replication_pod_name)
self._replication_interval = (
self.configuration.pure_replica_interval_default)
self._replication_retention_short_term = (
@ -1519,7 +1527,7 @@ class PureBaseVolumeDriver(san.SanDriver):
repl_type = self._get_replication_type_from_vol_type(
volume.volume_type)
if repl_type == REPLICATION_TYPE_SYNC:
base_name = REPLICATION_POD_NAME + "::" + base_name
base_name = self._replication_pod_name + "::" + base_name
return base_name + "-cinder"
@ -1547,7 +1555,7 @@ class PureBaseVolumeDriver(san.SanDriver):
# pod.
base_name = ""
if REPLICATION_TYPE_SYNC in self._group_potential_repl_types(pgroup):
base_name = REPLICATION_POD_NAME + "::"
base_name = self._replication_pod_name + "::"
return "%(base)sconsisgroup-%(id)s-cinder" % {
'base': base_name, 'id': pgroup.id}
@ -2068,6 +2076,9 @@ class PureBaseVolumeDriver(san.SanDriver):
@pure_driver_debug_trace
def _create_pod_if_not_exist(self, source_array, name):
if not name:
raise exception.PureDriverException(
reason=_("Empty string passed for Pod name."))
try:
source_array.create_pod(name)
except purestorage.PureHTTPError as err:
@ -2088,6 +2099,9 @@ class PureBaseVolumeDriver(san.SanDriver):
@pure_driver_debug_trace
def _create_protection_group_if_not_exist(self, source_array, pgname):
if not pgname:
raise exception.PureDriverException(
reason=_("Empty string passed for PG name."))
try:
source_array.create_pgroup(pgname)
except purestorage.PureHTTPError as err:
@ -2154,7 +2168,7 @@ class PureBaseVolumeDriver(san.SanDriver):
try:
secondary_array = array
# Ensure the pod is in a good state on the array
pod_info = secondary_array.get_pod(REPLICATION_POD_NAME)
pod_info = secondary_array.get_pod(self._replication_pod_name)
for pod_array in pod_info["arrays"]:
# Compare against Purity ID's
if pod_array["array_id"] == secondary_array.array_id:
@ -2251,7 +2265,7 @@ class PureBaseVolumeDriver(san.SanDriver):
replicated_vol_names = set()
for vol in array_volumes:
name = vol['name']
if name.startswith(REPLICATION_POD_NAME):
if name.startswith(self._replication_pod_name):
replicated_vol_names.add(name)
model_updates = []

View File

@ -244,9 +244,9 @@ To create a volume type that specifies replication to remote back ends with asyn
The following table contains the optional configuration parameters available
for async replication configuration with the Pure Storage array.
==================================================== ============= ======
==================================================== ============= ================
Option Description Default
==================================================== ============= ======
==================================================== ============= ================
``pure_replica_interval_default`` Snapshot
replication
interval in
@ -267,8 +267,25 @@ Option Description Default
on target
for this
time (in
days). ``7``
==================================================== ============= ======
days). ``7``
``pure_replication_pg_name`` Pure
Protection
Group name to
use for async
replication
(will be
created if
it does not
exist). ``cinder-group``
``pure_replication_pod_name`` Pure Pod name
to use for
sync
replication
(will be
created if
it does not
exist). ``cinder-pod``
==================================================== ============= ================
.. note::
@ -277,6 +294,12 @@ Option Description Default
multiple secondary arrays, but subsequent ``failover-host`` is only
supported back to the original primary array.
.. note::
``pure_replication_pg_name`` and ``pure_replication_pod_name`` should not
be changed after volumes have been created in the Cinder backend, as this
could have unexpected results in both replication and failover.
Automatic thin-provisioning/oversubscription ratio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,6 @@
---
features:
- |
Pure Storage FlashArray driver has added configuration options
``pure_replication_pg_name`` and ``pure_replication_pod_name`` for setting
the names for replication PGs and Pods.