[Pure Storage] Add new array status for replication capability

This patch adds a new field for the `get pools` command to show
what replication capability the backend array currently has.

This is based on the status of current array connections in the
backend array.

Response will be `async`, `sync`. `sync` or `trisync`.

`trisync` implies support for `sync` and `async`.
`sync` implies support for `async`.

Change-Id: I46cbb986ed73335270d6dd4ad197197648b55506
This commit is contained in:
Simon Dodsley 2023-01-25 13:42:17 -05:00
parent 7d25060243
commit a87eb13648
3 changed files with 92 additions and 1 deletions

View File

@ -4152,12 +4152,61 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
actual_ratio = self.driver._get_thin_provisioning(provisioned, used)
self.assertEqual(expected_ratio, actual_ratio)
@ddt.data(
dict(
connections=[
{'status': 'connected', 'type': 'sync-replication'},
],
expected='sync'),
dict(
connections=[
{'status': 'connected', 'type': 'async-replication'}
],
expected='async'),
dict(
connections=[
{'status': 'connected', 'type': 'async-replication'},
{'status': 'connected', 'type': 'sync-replication'},
{'status': 'connected', 'type': 'async-replication'}
],
expected='trisync'),
dict(
connections=[
{'status': 'connected', 'type': 'async-replication'},
{'status': 'connected', 'type': 'async-replication'}
],
expected='async'),
dict(
connections=[
{'status': 'connected', 'type': 'sync-replication'},
{'status': 'connected', 'type': 'sync-replication'}
],
expected='sync'),
dict(
connections=[
{'status': 'connected', 'type': 'sync-replication'},
{'status': 'connected', 'type': 'async-replication'}
],
expected='trisync'),
dict(
connections=[
{'status': 'connecting', 'type': 'sync-replication'}
],
expected=None))
@ddt.unpack
def test_get_replication_capability(self, connections, expected):
self.array.list_array_connections.return_value = connections
connection_status = self.driver._get_replication_capability()
self.assertEqual(expected, connection_status)
@mock.patch(BASE_DRIVER_OBJ + '._get_replication_capability')
@mock.patch(BASE_DRIVER_OBJ + '.get_goodness_function')
@mock.patch(BASE_DRIVER_OBJ + '.get_filter_function')
@mock.patch(BASE_DRIVER_OBJ + '._get_provisioned_space')
@mock.patch(BASE_DRIVER_OBJ + '._get_thin_provisioning')
def test_get_volume_stats(self, mock_get_thin_provisioning, mock_get_space,
mock_get_filter, mock_get_goodness):
mock_get_filter, mock_get_goodness,
mock_get_replication_capability):
filter_function = 'capabilities.total_volumes < 10'
goodness_function = '90'
num_hosts = 20
@ -4172,6 +4221,7 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
mock_get_space.return_value = (PROVISIONED_CAPACITY * units.Gi, 100)
mock_get_filter.return_value = filter_function
mock_get_goodness.return_value = goodness_function
mock_get_replication_capability.return_value = 'sync'
mock_get_thin_provisioning.return_value = (PROVISIONED_CAPACITY /
USED_SPACE)
@ -4203,6 +4253,7 @@ class PureVolumeUpdateStatsTestCase(PureBaseSharedDriverTestCase):
'usec_per_read_op': PERF_INFO['usec_per_read_op'],
'usec_per_write_op': PERF_INFO['usec_per_write_op'],
'queue_depth': PERF_INFO['queue_depth'],
'replication_capability': 'sync',
'replication_enabled': False,
'replication_type': [],
'replication_count': 0,

View File

@ -918,6 +918,7 @@ class PureBaseVolumeDriver(san.SanDriver):
data['queue_depth'] = perf_info['queue_depth']
# Replication
data["replication_capability"] = self._get_replication_capability()
data["replication_enabled"] = self._is_replication_enabled
repl_types = []
if self._is_replication_enabled:
@ -930,6 +931,39 @@ class PureBaseVolumeDriver(san.SanDriver):
in self._replication_target_arrays]
self._stats = data
def _get_replication_capability(self):
"""Discovered connected arrays status for replication"""
connections = self._get_current_array().list_array_connections()
is_sync, is_async, is_trisync = False, False, False
for conn in connections:
# If connection status is connected, we can have
# either sync or async replication
if conn["status"] == "connected":
# check for async replication
if conn["type"] == "async-replication":
is_async = True
# check for sync replication
elif conn["type"] == "sync-replication":
is_sync = True
# If we've connections for both sync and async
# replication, we can set trisync replication
# and exit the loop
if is_sync and is_async:
is_trisync = True
break
# Check if it is a trisync replication
if is_trisync:
replication_type = "trisync"
# If replication is not trisync, it will be either
# sync or async
elif is_sync:
replication_type = "sync"
elif is_async:
replication_type = "async"
else:
replication_type = None
return replication_type
def _get_provisioned_space(self):
"""Sum up provisioned size of all volumes on array"""
volumes = self._get_current_array().list_volumes(pending=True)

View File

@ -0,0 +1,6 @@
---
features:
- |
Pure Storage driver: Added replication capability to backend pool information.
Response will be ```async```, ```sync``` or```trisync```. ```sync``` implies
support for ```async``` and ```trisync``` implies support for ```sync``` and ```async```.