def _get_cluster_info(self): params = {} data = self._issue_api_request('GetClusterInfo', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) return data['result']
def create_volume_from_snapshot(self, volume, snapshot): cluster_info = self._get_cluster_info() iscsi_portal = cluster_info['clusterInfo']['svip'] + ':3260' sfaccount = self._create_sfaccount(snapshot['project_id']) chap_secret = sfaccount['targetSecret'] snapshot_name = 'OS-VOLID-%s' % volume['id'] (data, sf_account) = self._do_create_snapshot(snapshot, snapshot_name) if 'result' not in data or 'volumeID' not in data['result']: raise exception.SolidFireAPIDataException(data=data) volume_id = data['result']['volumeID'] volume_list = self._get_volumes_by_sfaccount(sf_account['accountID']) iqn = None for v in volume_list: if v['volumeID'] == volume_id: iqn = v['iqn'] break model_update = {} # NOTE(john-griffith): SF volumes are always at lun 0 model_update['provider_location'] = ('%s %s %s' % (iscsi_portal, iqn, 0)) model_update['provider_auth'] = ('CHAP %s %s' % (sfaccount['username'], chap_secret)) return model_update
def _do_volume_create(self, project_id, params): cluster_info = self._get_cluster_info() iscsi_portal = cluster_info['clusterInfo']['svip'] + ':3260' sfaccount = self._create_sfaccount(project_id) chap_secret = sfaccount['targetSecret'] params['accountID'] = sfaccount['accountID'] data = self._issue_api_request('CreateVolume', params) if 'result' not in data or 'volumeID' not in data['result']: raise exception.SolidFireAPIDataException(data=data) volume_id = data['result']['volumeID'] volume_list = self._get_volumes_by_sfaccount(sfaccount['accountID']) iqn = None for v in volume_list: if v['volumeID'] == volume_id: iqn = v['iqn'] break model_update = {} # NOTE(john-griffith): SF volumes are always at lun 0 model_update['provider_location'] = ('%s %s %s' % (iscsi_portal, iqn, 0)) model_update['provider_auth'] = ('CHAP %s %s' % (sfaccount['username'], chap_secret)) return model_update
def delete_volume(self, volume, is_snapshot=False): """Delete SolidFire Volume from device. SolidFire allows multipe volumes with same name, volumeID is what's guaranteed unique. """ LOG.debug(_("Enter SolidFire delete_volume...")) sf_account_name = socket.getfqdn() + '-' + volume['project_id'] sfaccount = self._get_sfaccount_by_name(sf_account_name) if sfaccount is None: raise exception.SfAccountNotFound(account_name=sf_account_name) params = {'accountID': sfaccount['accountID']} data = self._issue_api_request('ListVolumesForAccount', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) if is_snapshot: seek = 'OS-SNAPID-%s' % (volume['id']) else: seek = 'OS-VOLID-%s' % volume['id'] #params = {'name': 'OS-VOLID-:%s' % volume['id'], found_count = 0 volid = -1 for v in data['result']['volumes']: if v['name'] == seek: found_count += 1 volid = v['volumeID'] if found_count == 0: raise exception.VolumeNotFound(volume_id=volume['id']) if found_count > 1: LOG.debug(_("Deleting volumeID: %s"), volid) raise exception.DuplicateSfVolumeNames(vol_name=volume['id']) params = {'volumeID': volid} data = self._issue_api_request('DeleteVolume', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) LOG.debug(_("Leaving SolidFire delete_volume"))
def delete_volume(self, volume): """Delete SolidFire Volume from device. SolidFire allows multipe volumes with same name, volumeID is what's guaranteed unique. What we'll do here is check volumes based on account. this should work because nova will increment its volume_id so we should always get the correct volume. This assumes that nova does not assign duplicate ID's. """ LOG.debug(_("Enter SolidFire delete_volume...")) sf_account_name = socket.gethostname() + '-' + volume['project_id'] sfaccount = self._get_sfaccount_by_name(sf_account_name) if sfaccount is None: raise exception.SfAccountNotFound(account_name=sf_account_name) params = {'accountID': sfaccount['accountID']} data = self._issue_api_request('ListVolumesForAccount', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) found_count = 0 volid = -1 for v in data['result']['volumes']: if v['name'] == volume['name']: found_count += 1 volid = v['volumeID'] if found_count != 1: LOG.debug(_("Deleting volumeID: %s"), volid) raise exception.DuplicateSfVolumeNames(vol_name=volume['name']) params = {'volumeID': volid} data = self._issue_api_request('DeleteVolume', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) LOG.debug(_("Leaving SolidFire delete_volume"))
def _do_create_snapshot(self, snapshot, snapshot_name): """Creates a snapshot.""" LOG.debug(_("Enter SolidFire create_snapshot...")) sf_account_name = socket.getfqdn() + '-' + snapshot['project_id'] sfaccount = self._get_sfaccount_by_name(sf_account_name) if sfaccount is None: raise exception.SfAccountNotFound(account_name=sf_account_name) params = {'accountID': sfaccount['accountID']} data = self._issue_api_request('ListVolumesForAccount', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) found_count = 0 volid = -1 for v in data['result']['volumes']: if v['name'] == 'OS-VOLID-%s' % snapshot['volume_id']: found_count += 1 volid = v['volumeID'] if found_count == 0: raise exception.VolumeNotFound(volume_id=snapshot['volume_id']) if found_count != 1: raise exception.DuplicateSfVolumeNames(vol_name='OS-VOLID-%s' % snapshot['volume_id']) params = { 'volumeID': int(volid), 'name': snapshot_name, 'attributes': { 'OriginatingVolume': volid } } data = self._issue_api_request('CloneVolume', params) if 'result' not in data: raise exception.SolidFireAPIDataException(data=data) return (data, sfaccount)
def create_volume(self, volume): """Create volume on SolidFire device. The account is where CHAP settings are derived from, volume is created and exported. Note that the new volume is immediately ready for use. One caveat here is that an existing user account must be specified in the API call to create a new volume. We use a set algorithm to determine account info based on passed in nova volume object. First we check to see if the account already exists (and use it), or if it does not already exist, we'll go ahead and create it. For now, we're just using very basic settings, QOS is turned off, 512 byte emulation is off etc. Will be looking at extensions for these things later, or this module can be hacked to suit needs. """ LOG.debug(_("Enter SolidFire create_volume...")) GB = 1048576 * 1024 slice_count = 1 enable_emulation = False attributes = {} cluster_info = self._get_cluster_info() iscsi_portal = cluster_info['clusterInfo']['svip'] + ':3260' sfaccount = self._create_sfaccount(volume['project_id']) account_id = sfaccount['accountID'] account_name = sfaccount['username'] chap_secret = sfaccount['targetSecret'] params = { 'name': volume['name'], 'accountID': account_id, 'sliceCount': slice_count, 'totalSize': volume['size'] * GB, 'enable512e': enable_emulation, 'attributes': attributes } data = self._issue_api_request('CreateVolume', params) if 'result' not in data or 'volumeID' not in data['result']: raise exception.SolidFireAPIDataException(data=data) volume_id = data['result']['volumeID'] volume_list = self._get_volumes_by_sfaccount(account_id) iqn = None for v in volume_list: if v['volumeID'] == volume_id: iqn = 'iqn.2010-01.com.solidfire:' + v['iqn'] break model_update = {} # NOTE(john-griffith): SF volumes are always at lun 0 model_update['provider_location'] = ('%s %s %s' % (iscsi_portal, iqn, 0)) model_update['provider_auth'] = ('CHAP %s %s' % (account_name, chap_secret)) LOG.debug(_("Leaving SolidFire create_volume")) return model_update