예제 #1
0
    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']
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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"))
예제 #5
0
    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"))
예제 #6
0
    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)
예제 #7
0
    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