Merge "Dell PowerScale: add support for update share stats"

This commit is contained in:
Zuul
2025-08-12 15:57:34 +00:00
committed by Gerrit Code Review
5 changed files with 92 additions and 7 deletions

View File

@@ -31,8 +31,9 @@ from manila.share.drivers.dell_emc.plugins.isilon import isilon_api
"""Version history:
0.1.0 - Initial version
1.0.0 - Fix Http auth issue, SSL verification error and etc
1.0.1 - Add support for update share stats
"""
VERSION = "1.0.0"
VERSION = "1.0.1"
CONF = cfg.CONF
@@ -338,10 +339,31 @@ class IsilonStorageConnection(base.StorageConnection):
'max_over_subscription_ratio')
def update_share_stats(self, stats_dict):
"""TODO."""
# TODO(Shaun Edwards): query capacity, set storage_protocol,
# QoS support?
"""Retrieve stats info from share."""
stats_dict['driver_version'] = VERSION
stats_dict['storage_protocol'] = 'NFS_CIFS'
# PowerScale does not support pools.
# To align with manila scheduler 'pool-aware' strategic,
# report with one pool structure.
pool_stat = {
'pool_name': stats_dict['share_backend_name'],
'qos': False,
'reserved_percentage': self.reserved_percentage,
'reserved_snapshot_percentage':
self.reserved_snapshot_percentage,
'reserved_share_extend_percentage':
self.reserved_share_extend_percentage,
'max_over_subscription_ratio':
self.max_over_subscription_ratio
}
spaces = self._isilon_api.get_space_stats()
if spaces:
pool_stat['total_capacity_gb'] = spaces['total'] // units.Gi
pool_stat['free_capacity_gb'] = spaces['free'] // units.Gi
pool_stat['allocated_capacity_gb'] = spaces['used'] // units.Gi
stats_dict['pools'] = [pool_stat]
def get_network_allocations_number(self):
"""Returns number of network allocations for creating VIFs."""

View File

@@ -374,6 +374,25 @@ class IsilonApi(object):
return r.json()
LOG.error(f'Failed to lookup user {user_string}.')
def get_space_stats(self):
url = '{0}/platform/1/statistics/current'.format(self.host_url)
params = {'keys': 'ifs.bytes.free,ifs.bytes.total,ifs.bytes.used'}
r = self.send_get_request(url, params=params)
if r.status_code != 200:
raise exception.ShareBackendException(
msg=_('Failed to get statistics from PowerScale.')
)
stats = r.json()['stats']
spaces = {}
for stat in stats:
if stat['key'] == 'ifs.bytes.total':
spaces['total'] = stat['value']
elif stat['key'] == 'ifs.bytes.free':
spaces['free'] = stat['value']
elif stat['key'] == 'ifs.bytes.used':
spaces['used'] = stat['value']
return spaces
def request(self, method, url, headers=None, data=None, params=None):
if data is not None:
data = jsonutils.dumps(data)

View File

@@ -511,11 +511,32 @@ class IsilonTest(test.TestCase):
)
def test_update_share_stats(self):
stats_dict = {}
self._mock_isilon_api.get_space_stats.return_value = {
'total': 1000 * units.Gi,
'free': 100 * units.Gi,
'used': 1 * units.Gi,
}
stats_dict = {'share_backend_name': 'PowerScale_backend'}
self.storage_connection.update_share_stats(stats_dict)
expected_version = isilon.VERSION
self.assertEqual({'driver_version': expected_version}, stats_dict)
expected_pool_stats = {
'pool_name': 'PowerScale_backend',
'reserved_percentage': 0,
'reserved_snapshot_percentage': 0,
'reserved_share_extend_percentage': 0,
'max_over_subscription_ratio': None,
'total_capacity_gb': 1000,
'free_capacity_gb': 100,
'allocated_capacity_gb': 1,
'qos': False
}
expected_stats = {
'share_backend_name': 'PowerScale_backend',
'driver_version': isilon.VERSION,
'storage_protocol': 'NFS_CIFS',
'pools': [expected_pool_stats]
}
self.assertEqual(expected_stats, stats_dict)
def test_get_network_allocations_number(self):
# call method under test

View File

@@ -867,6 +867,25 @@ class IsilonApiTest(test.TestCase):
self.isilon_api.delete_quota,
quota_id)
def test_get_space_stats_success(self):
self.isilon_api.send_get_request = mock.MagicMock()
self.isilon_api.send_get_request.return_value.status_code = 200
self.isilon_api.send_get_request.return_value.json.return_value = {
'stats': [
{'key': 'ifs.bytes.free', 'value': 1000},
{'key': 'ifs.bytes.total', 'value': 2000},
{'key': 'ifs.bytes.used', 'value': 500}
]
}
result = self.isilon_api.get_space_stats()
self.assertEqual(result, {'total': 2000, 'free': 1000, 'used': 500})
def test_get_space_stats_failure(self):
self.isilon_api.send_get_request = mock.MagicMock()
self.isilon_api.send_get_request.return_value.status_code = 400
self.assertRaises(exception.ShareBackendException,
self.isilon_api.get_space_stats)
def test_modify_smb_share_access_with_host_acl_and_smb_permission(self):
self.isilon_api.send_put_request = mock.MagicMock()
share_name = 'my_share'

View File

@@ -0,0 +1,4 @@
---
features:
- |
Dell PowerScale Driver: Added support for update share stats.