Disable capabilities based on 3PAR licenses
The 3PAR firmware is now reporting which licenses are enabled on the storage array. The 3PAR drivers will now use this information to enable/disable standard stat reporting for thin provisioning, QoS support and replication DocImpact Implements: blueprint 3par-license-check Change-Id: Ib5fb06b1c029d026f6f38fa3fdf7d62c2005c06e
This commit is contained in:
parent
9c3cbdd90f
commit
6fddcf6da0
@ -5211,9 +5211,15 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
config.goodness_function = GOODNESS_FUNCTION
|
||||
mock_client = self.setup_driver(config=config)
|
||||
mock_client.getCPG.return_value = self.cpgs[0]
|
||||
# Purposely left out the Priority Optimization license in
|
||||
# getStorageSystemInfo to test that QoS_support returns False.
|
||||
mock_client.getStorageSystemInfo.return_value = {
|
||||
'id': self.CLIENT_ID,
|
||||
'serialNumber': '1234'
|
||||
'serialNumber': '1234',
|
||||
'licenseInfo': {
|
||||
'licenses': [{'name': 'Remote Copy'},
|
||||
{'name': 'Thin Provisioning (102400G)'}]
|
||||
}
|
||||
}
|
||||
|
||||
# cpg has no limit
|
||||
@ -5243,6 +5249,7 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
self.assertEqual('FC', stats['storage_protocol'])
|
||||
self.assertTrue(stats['pools'][0]['thin_provisioning_support'])
|
||||
self.assertTrue(stats['pools'][0]['thick_provisioning_support'])
|
||||
self.assertFalse(stats['pools'][0]['QoS_support'])
|
||||
self.assertEqual(86.0,
|
||||
stats['pools'][0]['provisioned_capacity_gb'])
|
||||
self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb'])
|
||||
@ -5285,6 +5292,7 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
self.assertEqual('FC', stats['storage_protocol'])
|
||||
self.assertTrue(stats['pools'][0]['thin_provisioning_support'])
|
||||
self.assertTrue(stats['pools'][0]['thick_provisioning_support'])
|
||||
self.assertFalse(stats['pools'][0]['QoS_support'])
|
||||
self.assertEqual(86.0,
|
||||
stats['pools'][0]['provisioned_capacity_gb'])
|
||||
self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb'])
|
||||
@ -5316,6 +5324,7 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
self.assertEqual('FC', stats['storage_protocol'])
|
||||
self.assertTrue(stats['pools'][0]['thin_provisioning_support'])
|
||||
self.assertTrue(stats['pools'][0]['thick_provisioning_support'])
|
||||
self.assertFalse(stats['pools'][0]['QoS_support'])
|
||||
total_capacity_gb = 8192 * const
|
||||
self.assertEqual(total_capacity_gb,
|
||||
stats['pools'][0]['total_capacity_gb'])
|
||||
@ -5364,9 +5373,16 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
config.goodness_function = GOODNESS_FUNCTION
|
||||
mock_client = self.setup_driver(config=config, wsapi_version=wsapi)
|
||||
mock_client.getCPG.return_value = self.cpgs[0]
|
||||
# Purposely left out the Thin Provisioning license in
|
||||
# getStorageSystemInfo to test that thin_provisioning_support returns
|
||||
# False.
|
||||
mock_client.getStorageSystemInfo.return_value = {
|
||||
'id': self.CLIENT_ID,
|
||||
'serialNumber': '1234'
|
||||
'serialNumber': '1234',
|
||||
'licenseInfo': {
|
||||
'licenses': [{'name': 'Remote Copy'},
|
||||
{'name': 'Priority Optimization'}]
|
||||
}
|
||||
}
|
||||
|
||||
# cpg has no limit
|
||||
@ -5383,6 +5399,8 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
|
||||
|
||||
stats = self.driver.get_volume_stats(True)
|
||||
self.assertEqual('FC', stats['storage_protocol'])
|
||||
self.assertFalse(stats['pools'][0]['thin_provisioning_support'])
|
||||
self.assertTrue(stats['pools'][0]['QoS_support'])
|
||||
self.assertEqual(24.0, stats['pools'][0]['total_capacity_gb'])
|
||||
self.assertEqual(3.0, stats['pools'][0]['free_capacity_gb'])
|
||||
self.assertEqual(87.5, stats['pools'][0]['capacity_utilization'])
|
||||
|
@ -218,10 +218,11 @@ class HPE3PARCommon(object):
|
||||
3.0.4 - Adds v2 managed replication support
|
||||
3.0.5 - Adds v2 unmanaged replication support
|
||||
3.0.6 - Adding manage/unmanage snapshot support
|
||||
3.0.7 - Enable standard capabilities based on 3PAR licenses
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "3.0.6"
|
||||
VERSION = "3.0.7"
|
||||
|
||||
stats = {}
|
||||
|
||||
@ -245,6 +246,11 @@ class HPE3PARCommon(object):
|
||||
EXTRA_SPEC_REP_SYNC_PERIOD = "replication:sync_period"
|
||||
RC_ACTION_CHANGE_TO_PRIMARY = 7
|
||||
|
||||
# License values for reported capabilities
|
||||
PRIORITY_OPT_LIC = "Priority Optimization"
|
||||
THIN_PROV_LIC = "Thin Provisioning"
|
||||
REMOTE_COPY_LIC = "Remote Copy"
|
||||
|
||||
# Valid values for volume type extra specs
|
||||
# The first value in the list is the default value
|
||||
valid_prov_values = ['thin', 'full', 'dedup']
|
||||
@ -1148,6 +1154,21 @@ class HPE3PARCommon(object):
|
||||
|
||||
pools = []
|
||||
info = self.client.getStorageSystemInfo()
|
||||
qos_support = True
|
||||
thin_support = True
|
||||
remotecopy_support = True
|
||||
if 'licenseInfo' in info:
|
||||
if 'licenses' in info['licenseInfo']:
|
||||
valid_licenses = info['licenseInfo']['licenses']
|
||||
qos_support = self._check_license_enabled(
|
||||
valid_licenses, self.PRIORITY_OPT_LIC,
|
||||
"QoS_support")
|
||||
thin_support = self._check_license_enabled(
|
||||
valid_licenses, self.THIN_PROV_LIC,
|
||||
"Thin_provisioning_support")
|
||||
remotecopy_support = self._check_license_enabled(
|
||||
valid_licenses, self.REMOTE_COPY_LIC,
|
||||
"Replication")
|
||||
|
||||
for cpg_name in self.config.hpe3par_cpg:
|
||||
try:
|
||||
@ -1210,8 +1231,8 @@ class HPE3PARCommon(object):
|
||||
'total_capacity_gb': total_capacity,
|
||||
'free_capacity_gb': free_capacity,
|
||||
'provisioned_capacity_gb': provisioned_capacity,
|
||||
'QoS_support': True,
|
||||
'thin_provisioning_support': True,
|
||||
'QoS_support': qos_support,
|
||||
'thin_provisioning_support': thin_support,
|
||||
'thick_provisioning_support': True,
|
||||
'max_over_subscription_ratio': (
|
||||
self.config.safe_get('max_over_subscription_ratio')),
|
||||
@ -1234,7 +1255,8 @@ class HPE3PARCommon(object):
|
||||
'consistencygroup_support': True,
|
||||
}
|
||||
|
||||
if hpe3parclient.version >= MIN_REP_CLIENT_VERSION:
|
||||
if (hpe3parclient.version >= MIN_REP_CLIENT_VERSION
|
||||
and remotecopy_support):
|
||||
pool['replication_enabled'] = self._replication_enabled
|
||||
pool['replication_type'] = ['sync', 'periodic']
|
||||
pool['replication_count'] = len(self._replication_targets)
|
||||
@ -1247,6 +1269,19 @@ class HPE3PARCommon(object):
|
||||
'volume_backend_name': None,
|
||||
'pools': pools}
|
||||
|
||||
def _check_license_enabled(self, valid_licenses,
|
||||
license_to_check, capability):
|
||||
"""Check a license against valid licenses on the array."""
|
||||
if valid_licenses:
|
||||
for license in valid_licenses:
|
||||
if license_to_check in license.get('name'):
|
||||
return True
|
||||
LOG.debug(("'%(capability)s' requires a '%(license)s' "
|
||||
"license which is not installed.") %
|
||||
{'capability': capability,
|
||||
'license': license_to_check})
|
||||
return False
|
||||
|
||||
def _get_vlun(self, volume_name, hostname, lun_id=None, nsp=None):
|
||||
"""find a VLUN on a 3PAR host."""
|
||||
vluns = self.client.getHostVLUNs(hostname)
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Disable standard capabilities based on 3PAR licenses.
|
Loading…
Reference in New Issue
Block a user