def set_rmcache_size(self, sds_id, rmcache_size): """Set Rmcache size for PowerFlex SDS. :type sds_id: str :type rmcache_size: int :rtype: dict """ action = 'setSdsRmcacheSize' params = dict(rmcacheSizeInMB=rmcache_size) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set Rmcache size for PowerFlex {entity} ' 'with id {_id}. Error: {response}'.format( entity=self.entity, _id=sds_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=sds_id)
def set_port(self, sds_id, sds_port): """Set PowerFlex SDS port. :type sds_id: str :type sds_port: int :rtype: dict """ action = 'setSdsPort' params = dict(sdsPort=sds_port) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set port for PowerFlex {entity} ' 'with id {_id}. Error: {response}'.format( entity=self.entity, _id=sds_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=sds_id)
def set_performance_parameters(self, sds_id, performance_profile): """Set performance parameters for PowerFlex SDS. :type sds_id: str :type performance_profile: str :rtype: dict """ action = 'setSdsPerformanceParameters' params = dict(perfProfile=performance_profile) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set performance parameters for PowerFlex ' '{entity} with id {_id}. Error: {response}'.format( entity=self.entity, _id=sds_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=sds_id)
def set_ip_role(self, sds_id, ip, role, force=None): """Set PowerFlex SDS IP-address role. :type sds_id: str :type ip: str :param role: one of predefined attributes of SdsIpRoles :type role: str :type force: bool :rtype: dict """ action = 'setSdsIpRole' params = dict(sdsIpToSet=ip, newRole=role, forceRoleModification=force) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set ip role for PowerFlex {entity} ' 'with id {_id}. Error: {response}'.format( entity=self.entity, _id=sds_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=sds_id)
def set_use_rmcache(self, volume_id, use_rmcache): """ Control the use of Read RAM Cache in the specified volume. If you want to ensure that all I/O operations for this volume are cached, the relevant Storage Pool should be configured to use cache, and the relevant SDSs should all have caching enabled. :param volume_id: ID of the volume :type volume_id: str :param use_rmcache: Whether to use Read RAM cache or not :type use_rm_cache: bool :return: dict """ action = 'setVolumeUseRmcache' params = dict(useRmcache=use_rmcache) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to update the use_rmcache of PowerFlex' ' {entity} with id {_id}. ' 'Error: {response}'.format(entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def set_media_type(self, device_id, media_type): """Set PowerFlex device media type. :type device_id: str :param media_type: one of predefined attributes of MediaType :type media_type: str :rtype: dict """ action = 'setMediaType' params = dict(mediaType=media_type) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=device_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set media type for PowerFlex {entity} ' 'with id {_id}. Error: {response}'.format( entity=self.entity, _id=device_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=device_id)
def remove_ip(self, sds_id, ip): """Remove PowerFlex SDS IP-address. :type sds_id: str :type ip: str :rtype: dict """ action = 'removeSdsIp' params = dict(ip=ip) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to remove IP from PowerFlex {entity} ' 'with id {_id}. Error: {response}'.format( entity=self.entity, _id=sds_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=sds_id)
def set_spare_percentage(self, storage_pool_id, spare_percentage): """Set spare percentage for PowerFlex storage pool. :type storage_pool_id: str :type spare_percentage: int :rtype: dict """ action = 'setSparePercentage' params = dict( sparePercentage=spare_percentage ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set spare percentage for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def unlock_auto_snapshot(self, volume_id, remove_auto_snapshot=None): """Unlock auto snapshot of PowerFlex volume. :param volume_id: str :param remove_auto_snapshot: bool :return: dict """ action = 'unlockAutoSnapshot' params = dict(autoSnapshotWillBeRemoved=remove_auto_snapshot) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to unlock AutoSnapshot for PowerFlex {entity} ' 'with id {_id}. Error: ' '{response}'.format(entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def set_compression_method(self, volume_id, compression_method): """ Modify the compression method to be used for a Volume, relevant only if the volume has a space efficient data layout. :param volume_id: ID of the volume :type volume_id: str :param compression_method: one of predefined attributes of CompressionMethod :type compression_method: str :return: dict """ action = 'modifyCompressionMethod' params = dict(compressionMethod=compression_method, ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to update the compression method of PowerFlex' ' {entity} with id' ' {_id}. Error: {response}'.format(entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def activate(self, protection_domain_id, force=None): """Activate PowerFlex protection domain. :type protection_domain_id: str :type force: bool :rtype: dict """ action = 'activateProtectionDomain' params = dict( forceActivate=force ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=protection_domain_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to activate PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=protection_domain_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=protection_domain_id)
def extend(self, volume_id, size_in_gb, allow_ext_managed=None): """Extend PowerFlex volume. :param volume_id: str :param size_in_gb: int :param allow_ext_managed: bool :return: dict """ action = 'setVolumeSize' params = dict(sizeInGB=size_in_gb, allowOnExtManagedVol=allow_ext_managed) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to extend PowerFlex {entity} with id {_id}. ' 'Error: {response}'.format(entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def remove_cg_snapshots(self, system_id, cg_id, allow_ext_managed=None): """Remove PowerFlex ConsistencyGroup snapshots. :type system_id: str :type cg_id: str :type allow_ext_managed: bool :rtype: dict """ action = 'removeConsistencyGroupSnapshots' params = dict(snapGroupId=cg_id, allowOnExtManagedVol=allow_ext_managed) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=system_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to remove consistency group snapshots from ' 'PowerFlex {entity} with ' 'id {_id}.'.format(entity=self.entity, _id=system_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response
def api_version(self, cached=True): """Get PowerFlex API version. :param cached: get version from cache or send API response :type cached: bool :rtype: str """ url = '/version' if not self.__api_version or not cached: r, response = self.send_get_request(url) if r.status_code != requests.codes.ok: exc = exceptions.PowerFlexFailQuerying('API version') LOG.error(exc.message) raise exc pattern = re.compile(r'^\d+(\.\d+)*$') if not pattern.match(response): msg = ( 'Failed to query PowerFlex API version. Invalid version ' 'format: {response}.'.format(response=r.text)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) self.__api_version = response return self.__api_version
def snapshot_volumes(self, system_id, snapshot_defs, allow_ext_managed=None): """Create snapshots of PowerFlex volumes. :type system_id: str :type snapshot_defs: list[dict] :type allow_ext_managed: bool :rtype: dict """ action = 'snapshotVolumes' params = dict(snapshotDefs=snapshot_defs, allowOnExtManagedVol=allow_ext_managed) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=system_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to snapshot volumes on PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=system_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response
def set_retention_period(self, snap_id, retention_period): """ Set a new retention period for the given snapshot. If the snapshot is already secure, then it can be delayed but not advanced. :param snap_id: ID of the volume :type snap_id: str :param retention_period: Retention period for the specified resource :type retention_period: str :return: dict """ action = 'setSnapshotSecurity' params = dict(retentionPeriodInMin=retention_period, ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=snap_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set the retention period for PowerFlex' ' {entity} with id {_id}.' ' Error: {response}'.format(entity=self.entity, _id=snap_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=snap_id)
def set_access_mode_for_sdc(self, volume_id, sdc_id, access_mode): """ Set the volume access mode for the specified SDC mapped to the volume. :param volume_id: ID of the volume :type volume_id: str :param access_mode: The access mode of the volume for the mapped SDC :type access_mode: str :param sdc_id: ID of the SDC. :type sdc_id: str :return: dict """ action = 'setVolumeMappingAccessMode' params = dict(accessMode=access_mode, sdcId=sdc_id) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set the access mode for the SDC {sdc_id}' ' mapped to PowerFlex {entity} with id {_id}. Error:' ' {response}'.format(entity=self.entity, _id=volume_id, sdc_id=sdc_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def set_rebuild_enabled(self, storage_pool_id, rebuild_enabled): """Enable/disable rebuild for PowerFlex storage pool. :type storage_pool_id: str :type rebuild_enabled: bool :rtype: dict """ action = 'setRebuildEnabled' params = dict( rebuildEnabled=rebuild_enabled ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to enable/disable rebuild for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def set_volume_access_mode_limit(self, volume_id, access_mode_limit): """ Set the highest mapping access mode allowed for a volume. :param volume_id: ID of the volume :type volume_id: str :param access_mode_limit: Define the access mode limit of a volume, options are ReadWrite or ReadOnly :type access_mode_limit: str :return: dict """ action = 'setVolumeAccessModeLimit' params = dict(accessModeLimit=access_mode_limit) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ( 'Failed to update the Volume Access Mode Limit of ' 'PowerFlex {entity} with id {_id}. Error: {response}'.format( entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def set_use_rmcache(self, storage_pool_id, use_rmcache): """Enable/disable Rmcache usage for PowerFlex storage pool. :type storage_pool_id: str :type use_rmcache: boold :rtype: dict """ action = 'setUseRmcache' params = dict( useRmcache=use_rmcache ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set Rmcache usage for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def set_media_type(self, storage_pool_id, media_type, override_device_configuration=None): """Set media type for PowerFlex storage pool. :type storage_pool_id: str :param media_type: one of predefined attributes of MediaType :type media_type: str :type override_device_configuration: bool :rtype: dict """ action = 'setMediaType' params = dict( mediaType=media_type, overrideDeviceConfiguration=override_device_configuration ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set media type for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def set_compression_method(self, storage_pool_id, compression_method): """Set compression method for PowerFlex storage pool. :type storage_pool_id: str :type compression_method: str :rtype: dict """ action = 'modifyCompressionMethod' params = dict( compressionMethod=compression_method ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set compression method for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def modify(self, snapshot_policy_id, auto_snap_creation_cadence_in_min, retained_snaps_per_level): """Modify PowerFlex snapshot policy. :type snapshot_policy_id: str :type auto_snap_creation_cadence_in_min: int :type retained_snaps_per_level: list[int] :rtype: dict """ action = 'modifySnapshotPolicy' params = dict( autoSnapshotCreationCadenceInMin=auto_snap_creation_cadence_in_min, numOfRetainedSnapshotsPerLevel=retained_snaps_per_level ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=snapshot_policy_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to modify PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=snapshot_policy_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=snapshot_policy_id)
def add_source_volume(self, snapshot_policy_id, volume_id): """Add source volume to PowerFlex snapshot policy. :type snapshot_policy_id: str :type volume_id: str :rtype: dict """ action = 'addSourceVolumeToSnapshotPolicy' params = dict( sourceVolumeId=volume_id ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=snapshot_policy_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to add source volume to PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=snapshot_policy_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=snapshot_policy_id)
def set_zero_padding_policy(self, storage_pool_id, zero_padding_enabled): """Enable/disable zero padding for PowerFlex storage pool. :type storage_pool_id: str :type zero_padding_enabled: bool :rtype: dict """ action = 'setZeroPaddingPolicy' params = dict( zeroPadEnabled=zero_padding_enabled ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set Zero Padding policy for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def remove_mapped_sdc(self, volume_id, sdc_id=None, sdc_guid=None, all_sdcs=None, skip_appliance_validation=None, allow_ext_managed=None): """Unmap PowerFlex volume from SDC. :param volume_id: str :param sdc_id: str :param sdc_guid: str :param all_sdcs: bool :param skip_appliance_validation: bool :param allow_ext_managed: bool :return: dict """ action = 'removeMappedSdc' if ( all([sdc_id, sdc_guid, all_sdcs]) or not any([sdc_id, sdc_guid, all_sdcs]) ): msg = 'Either sdc_id or sdc_guid or all_sdcs must be set.' raise exceptions.InvalidInput(msg) params = dict( sdcId=sdc_id, guid=sdc_guid, allSdcs=all_sdcs, skipApplianceValidation=skip_appliance_validation, allowOnExtManagedVol=allow_ext_managed ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to unmap PowerFlex {entity} with id {_id} ' 'from SDC.'.format(entity=self.entity, _id=volume_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def initialize(self): self.configuration.validate() self.__add_storage_entity('device', objects.Device) self.__add_storage_entity('fault_set', objects.FaultSet) self.__add_storage_entity('protection_domain', objects.ProtectionDomain) self.__add_storage_entity('sdc', objects.Sdc) self.__add_storage_entity('sds', objects.Sds) self.__add_storage_entity('snapshot_policy', objects.SnapshotPolicy) self.__add_storage_entity('storage_pool', objects.StoragePool) self.__add_storage_entity('system', objects.System) self.__add_storage_entity('volume', objects.Volume) utils.init_logger(self.configuration.log_level) if version.parse(self.system.api_version()) < version.Version('3.0'): raise exceptions.PowerFlexClientException( 'PowerFlex (VxFlex OS) versions lower than ' '3.0 are not supported.') self.__is_initialized = True
def add_mapped_sdc(self, volume_id, sdc_id=None, sdc_guid=None, allow_multiple_mappings=None, allow_ext_managed=None, access_mode=None): """Map PowerFlex volume to SDC. :param volume_id: str :param sdc_id: str :param sdc_guid: str :param allow_multiple_mappings: bool :param allow_ext_managed: bool :type access_mode: str :return: dict """ action = 'addMappedSdc' if all([sdc_id, sdc_guid]) or not any([sdc_id, sdc_guid]): msg = 'Either sdc_id or sdc_guid must be set.' raise exceptions.InvalidInput(msg) params = dict(sdcId=sdc_id, guid=sdc_guid, allowMultipleMappings=allow_multiple_mappings, allowOnExtManagedVol=allow_ext_managed, accessMode=access_mode) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to map PowerFlex {entity} with id {_id} ' 'to SDC. Error: {response}'.format(entity=self.entity, _id=volume_id, response=response)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)
def set_external_acceleration_type( self, storage_pool_id, external_acceleration_type, override_device_configuration=None, keep_device_ext_acceleration=None ): """Set external acceleration type for PowerFlex storage pool. :type storage_pool_id: str :param external_acceleration_type: one of predefined attributes of ExternalAccelerationType :type external_acceleration_type: str :type override_device_configuration: bool :type keep_device_ext_acceleration: bool :rtype: dict """ action = 'setExternalAccelerationType' if all([override_device_configuration, keep_device_ext_acceleration]): msg = ('Either override_device_configuration or ' 'keep_device_specific_external_acceleration can be set.') raise exceptions.InvalidInput(msg) params = dict( externalAccelerationType=external_acceleration_type, overrideDeviceConfiguration=override_device_configuration, keepDeviceSpecificExternalAcceleration=keep_device_ext_acceleration ) r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: msg = ('Failed to set external acceleration type for PowerFlex ' '{entity} with id {_id}.'.format(entity=self.entity, _id=storage_pool_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id)
def lock_auto_snapshot(self, volume_id): """Lock auto snapshot of PowerFlex volume. :param volume_id: str :return: dict """ action = 'lockAutoSnapshot' r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=volume_id) if r.status_code != requests.codes.ok: msg = ('Failed to lock AutoSnapshot for PowerFlex {entity} ' 'with id {_id}.'.format(entity=self.entity, _id=volume_id)) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=volume_id)