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
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'])
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'])
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'])
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
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'])
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 = {}
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']
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:
'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')),
'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)
'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)