def _delete_snapshot(self, name, volume_name): """Delets a snapshot of specified volume.""" request_urn = ('%s/%s/%s@%s/') % (FreeNASServer.REST_API_SNAPSHOT, self.configuration.ixsystems_datastore_pool, volume_name, name) try: ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting snapshot: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) except Exception as e: raise FreeNASApiError('Unexpected error', e)
def _create_extent(self, name, volume_name, from_snapshot=False): ext_params = {} if from_snapshot: ext_params['Source'] = volume_name else: ext_params['iscsi_target_extent_type'] = 'Disk' ext_params['iscsi_target_extent_name'] = name mnt_point = ('zvol/%s/%s') % ( self.configuration.ixsystems_datastore_pool, volume_name) ext_params['iscsi_target_extent_disk'] = mnt_point request_urn = ('%s/') % (FreeNASServer.REST_API_EXTENT) extent = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, json.dumps(ext_params)) LOG.debug('_create_iscsitarget extent response : %s', json.dumps(extent)) if extent['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating iscsi target extent: %s' % extent['response']) raise FreeNASApiError('Unexpected error', msg) return json.loads(extent['response'])['id']
def _create_target(self, name): targetgroup_params = [ {} ] # v2.0 API - targetgroup can now be added when target is created targetgroup_params[0]['portal'] = int( self.configuration.ixsystems_portal_id ) #TODO: Decide to create portal or not targetgroup_params[0]['initiator'] = int( self.configuration.ixsystems_initiator_id ) #TODO: Decide to create initiator or not tgt_params = {} tgt_params['name'] = name tgt_params['groups'] = targetgroup_params jtgt_params = json.dumps(tgt_params) jtgt_params = jtgt_params.encode('utf8') LOG.debug('_create_target params : %s', json.dumps(tgt_params)) request_urn = ('%s/') % (FreeNASServer.REST_API_TARGET) target = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jtgt_params) LOG.debug('_create_target response : %s', json.dumps(target)) if target['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating iscsi target: %s' % target['response']) raise FreeNASApiError('Unexpected error', msg) target_id = json.loads(target['response'])['id'] # self._create_target_group(target_id) return target_id
def _target_to_extent(self, target_id, extent_id): """Create relationship between iscsi target to iscsi extent""" LOG.debug('_target_to_extent target id : %s extend id : %s', target_id, extent_id) request_urn = ('%s/') % (FreeNASServer.REST_API_TARGET_TO_EXTENT) params = {} params['target'] = target_id params['extent'] = extent_id # params['iscsi_lunid'] = 0 # no longer needed with API v2.0 jparams = json.dumps(params) jparams = jparams.encode('utf8') LOG.debug('_create_target_to_extent params : %s', json.dumps(params)) tgt_ext = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jparams) LOG.debug('_target_to_extent response : %s', json.dumps(tgt_ext)) if tgt_ext['status'] != FreeNASServer.STATUS_OK: msg = ( 'Error while creating relation between target and extent: %s' % tgt_ext['response']) raise FreeNASApiError('Unexpected error', msg)
def _create_snapshot(self, name, volume_name): """Creates a snapshot of specified volume.""" args = {} args['dataset'] = ('%s/%s') % (self.configuration.ixsystems_datastore_pool, volume_name) args['name'] = name jargs = json.dumps(args) request_urn = ('%s/') % (FreeNASServer.REST_API_SNAPSHOT) LOG.debug('_create_snapshot urn : %s', request_urn) try: ret = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jargs) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating snapshot: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) except Exception as e: raise FreeNASApiError('Unexpected error', e)
def _delete_snapshot(self, name, volume_name): """Delets a snapshot of specified volume.""" LOG.debug('_delete_snapshot, deleting name: %s from volume: %s', name, volume_name) request_urn = ('%s/id/%s@%s') % ( FreeNASServer.REST_API_SNAPSHOT, urllib.parse.quote_plus(self.configuration.ixsystems_dataset_path + '/' + volume_name), name) LOG.debug('_delete_snapshot urn : %s', request_urn) try: ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) LOG.debug('_delete_snapshot response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting snapshot: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) except Exception as e: raise FreeNASApiError('Unexpected error', e)
def _create_volume_from_snapshot(self, name, snapshot_name, snap_zvol_name): "creates a volume from snapshot" LOG.debug('create_volume_from_snapshot') args = {} args['name'] = ('%s/%s') % (self.configuration.ixsystems_datastore_pool, name) jargs = json.dumps(args) request_urn = ('%s/%s/%s@%s/%s/') % (FreeNASServer.REST_API_SNAPSHOT, self.configuration.ixsystems_datastore_pool, snap_zvol_name, snapshot_name, FreeNASServer.CLONE) try: ret = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jargs) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating snapshot: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) except Exception as e: raise FreeNASApiError('Unexpected error', e)
def delete_target(self, target_id): if target_id: request_urn = ('%s/%s/') % (FreeNASServer.REST_API_TARGET, target_id) LOG.debug('_delete_iscsitarget urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting iscsi target: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _delete_volume(self, name): """Deletes specified volume """ request_urn = ('%s/%s/%s/%s/') % (FreeNASServer.REST_API_VOLUME, self.configuration.ixsystems_datastore_pool, FreeNASServer.ZVOLS, name) LOG.debug('_delete_volume urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _do_custom_setup(self): """Setup iXsystems FREENAS driver.""" self._create_handle( hostname=self.configuration.ixsystems_server_hostname, port=self.configuration.ixsystems_server_port, login=self.configuration.ixsystems_login, password=self.configuration.ixsystems_password, api_version=self.configuration.ixsystems_api_version, transport_type=self.configuration.ixsystems_transport_type) if not self.handle: raise FreeNASApiError("Failed to create handle for FREENAS server")
def delete_extent(self, extent_id): if extent_id: request_urn = ('%s/id/%s') % (FreeNASServer.REST_API_EXTENT, extent_id) LOG.debug('delete_extent urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) LOG.debug('delete_extent response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting iscsi extent: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _extend_volume(self, name, new_size): """Extend an existing volumes size.""" LOG.debug('_extend__volume name: %s', name) params = {} params['volsize'] = str(new_size) + 'G' jparams = json.dumps(params) request_urn = ('%s/%s/%s/%s/') % (FreeNASServer.REST_API_VOLUME, self.configuration.ixsystems_datastore_pool, FreeNASServer.ZVOLS, name) ret = self.handle.invoke_command(FreeNASServer.UPDATE_COMMAND, request_urn, jparams) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while extending volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _create_handle(self, **kwargs): """Instantiate handle (client) for API communication with iXsystems FREENAS server """ host_system = kwargs['hostname'] LOG.debug('Using iXsystems FREENAS server: %s', host_system) self.handle = FreeNASServer(host=host_system, port=kwargs['port'], username=kwargs['login'], password=kwargs['password'], api_version=kwargs['api_version'], transport_type=kwargs['transport_type'], style=FreeNASServer.STYLE_LOGIN_PASSWORD) if not self.handle: raise FreeNASApiError("Failed to create handle for FREENAS server")
def get_extent_id(self, name): """Get Extent ID from Extent Name """ request_urn = ('%s/') % (FreeNASServer.REST_API_EXTENT) ret = self.handle.invoke_command(FreeNASServer.SELECT_COMMAND, request_urn, None) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting iscsi target: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) resp = json.loads(ret['response']) try: return (item for item in resp if item["iscsi_target_extent_name"] == name).next()['id'] except StopIteration: return 0
def _create_volume_from_snapshot(self, name, snapshot_name, snap_zvol_name): """creates a volume from a snapshot""" args = {} args['snapshot'] = ( '%s/%s@%s') % (self.configuration.ixsystems_dataset_path, snap_zvol_name, snapshot_name) args['dataset_dst'] = ('%s/%s') % ( self.configuration.ixsystems_dataset_path, name) jargs = json.dumps(args) jargs = jargs.encode("utf8") request_urn = ('%s/%s') % (FreeNASServer.REST_API_SNAPSHOT, FreeNASServer.CLONE) LOG.debug('_create_volume_from_snapshot urn : %s', request_urn) try: ret = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jargs) LOG.debug('_create_volume_from_snapshot response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating snapshot: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) except Exception as e: raise FreeNASApiError('Unexpected error', e)
def _dependent_clone(self, name): """ returns the fullname of any snapshot used to create volume 'name' """ request_urn = ('%s/id/%s%s') % ( FreeNASServer.REST_API_VOLUME, urllib.parse.quote_plus(self.configuration.ixsystems_dataset_path + '/'), name) LOG.debug('_dependent_clones urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.SELECT_COMMAND, request_urn, None) LOG.debug('_dependent_clones response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while getting volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) uresp = ret['response'] resp = json.loads(uresp.decode('utf8')) return resp['origin']['value']
def _extend_volume(self, name, new_size): """Extend an existing volumes size.""" LOG.debug('_extend__volume name: %s', name) params = {} params['volsize'] = ix_utils.get_bytes_from_gb(new_size) jparams = json.dumps(params) jparams = jparams.encode('utf8') request_urn = ('%s/id/%s') % ( FreeNASServer.REST_API_VOLUME, urllib.parse.quote_plus(self.configuration.ixsystems_dataset_path + '/' + name)) ret = self.handle.invoke_command(FreeNASServer.UPDATE_COMMAND, request_urn, jparams) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while extending volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _create_volume(self, name, size): """Creates a volume of specified size """ params = {} params['name'] = name params['volsize'] = str(size) + 'G' jparams = json.dumps(params) request_urn = ('%s/%s/%s/') % (FreeNASServer.REST_API_VOLUME, self.configuration.ixsystems_datastore_pool, FreeNASServer.ZVOLS) LOG.debug('_create_volume params : %s', params) LOG.debug('_create_volume urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jparams) LOG.debug('_create_volume response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def _create_target_group(self, target_id): tgt_grp_params = {} tgt_grp_params["iscsi_target"] = target_id tgt_grp_params["iscsi_target_portalgroup"] = self.configuration.ixsystems_portal_id #TODO: Decide to create portal or not tgt_grp_params["iscsi_target_initiatorgroup"] = self.configuration.ixsystems_initiator_id #TODO: Decide to create initiator or not tgt_request_urn = ('%s/') % (FreeNASServer.REST_API_TARGET_GROUP) tgtgrp = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, tgt_request_urn, json.dumps(tgt_grp_params)) LOG.debug('_create_target_group response : %s', json.dumps(tgtgrp)) if tgtgrp['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating iscsi target: %s' % tgtgrp['response']) raise FreeNASApiError('Unexpected error', msg)
def _create_volume(self, name, size): """Creates a volume of specified size """ params = {} params['name'] = self.configuration.ixsystems_dataset_path + '/' + name params['type'] = 'VOLUME' params['volsize'] = ix_utils.get_bytes_from_gb(size) jparams = json.dumps(params) jparams = jparams.encode('utf8') request_urn = ('%s') % (FreeNASServer.REST_API_VOLUME) LOG.debug('_create_volume params : %s', params) LOG.debug('_create_volume urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, jparams) LOG.debug('_create_volume response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)
def get_extent_id(self, name): """Get Extent ID from Extent Name """ request_urn = ('%s') % (FreeNASServer.REST_API_EXTENT) LOG.debug('get_extent_id urn : %s', request_urn) ret = self.handle.invoke_command(FreeNASServer.SELECT_COMMAND, request_urn, None) LOG.debug('get_extent_id response : %s', json.dumps(ret)) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while getting extent id: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg) uresp = ret['response'] resp = json.loads(uresp.decode('utf8')) try: return (item for item in resp if item['name'] == name).__next__()['id'] except StopIteration: return 0
def _create_target(self, name): tgt_params = {} tgt_params["iscsi_target_name"] = name LOG.debug('_create_target params : %s', json.dumps(tgt_params)) request_urn = ('%s/') % (FreeNASServer.REST_API_TARGET) target = self.handle.invoke_command(FreeNASServer.CREATE_COMMAND, request_urn, json.dumps(tgt_params)) LOG.debug('_create_target response : %s', json.dumps(target)) if target['status'] != FreeNASServer.STATUS_OK: msg = ('Error while creating iscsi target: %s' % target['response']) raise FreeNASApiError('Unexpected error', msg) target_id = json.loads(target['response'])['id'] self._create_target_group(target_id) return target_id
def _delete_volume(self, name): """Deletes specified volume """ request_urn = ('%s/id/%s%s') % ( FreeNASServer.REST_API_VOLUME, urllib.parse.quote_plus(self.configuration.ixsystems_dataset_path + '/'), name) LOG.debug('_delete_volume urn : %s', request_urn) clone = self._dependent_clone( name) # add check for dependent clone, if exists will delete ret = self.handle.invoke_command(FreeNASServer.DELETE_COMMAND, request_urn, None) LOG.debug('_delete_volume response : %s', json.dumps(ret)) if clone: # delete the cloned-from snapshot. Must check before deleting volume, but delete snapshot after fullvolume, snapname = clone.split('@') temp, snapvol = fullvolume.rsplit('/', 1) self._delete_snapshot(snapname, snapvol) if ret['status'] != FreeNASServer.STATUS_OK: msg = ('Error while deleting volume: %s' % ret['response']) raise FreeNASApiError('Unexpected error', msg)