Пример #1
0
 def __init__(self, *args, **kwargs):
     super(VmProxy, self).__init__()
     self.task_proxy = TaskProxy()
Пример #2
0
 def __init__(self):
     super(VolumeProxy, self).__init__()
     self.task_proxy = TaskProxy()
Пример #3
0
class VmProxy(BaseProxy):
    '''
    VmProxy
    '''
    def __init__(self, *args, **kwargs):
        super(VmProxy, self).__init__()
        self.task_proxy = TaskProxy()


    def query_vm(self, **kwargs):
        '''
        'query_vm': ('GET',
                     ('/vms', None, kwargs.get('vm_id'), None),
                     {},
                     {},
                     False)
        '''
        LOG.debug(_("[VRM-CINDER] start query_vm()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return body

    def query_vm_by_uri(self, **kwargs):
        '''
        'query_vm': ('GET',
                     ('/vms', None, kwargs.get('vm_id'), None),
                     {},
                     {},
                     False)
        '''
        LOG.debug(_("[VRM-CINDER] start query_vm()"))
        method = 'GET'
        path = kwargs.get('vm_uri')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return body

    def delete_vm(self, **kwargs):
        '''
                'delete_vm': ('DELETE',
                              ('/vms', None, kwargs.get('vm_id'), None),
                              {},
                              {},
                              True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_vm()"))
        uri = '/vms'
        method = 'DELETE'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def detach_vol_from_vm(self, **kwargs):
        '''
                'detach_vol_from_vm': ('POST',
                                       ('/vms', None, kwargs.get('vm_id'), 'action/detachvol'),
                                       {},
                                       {'volUrn': kwargs.get('volUrn')},
                                       True),
        '''
        LOG.debug(_("[VRM-CINDER] start detach_vol_from_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/detachvol'
        new_url = self._generate_url(path)
        body = {'volUrn': kwargs.get('volume_urn')}
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def attach_vol_to_vm(self, **kwargs):
        '''
                'attach_vol_to_vm': ('POST',
                                       ('/vms', None, kwargs.get('vm_id'), 'action/attachvol'),
                                       {},
                                       {'volUrn': kwargs.get('volUrn')},
                                       True),
        '''
        LOG.debug(_("[VRM-CINDER] start attach_vol_to_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/attachvol'
        new_url = self._generate_url(path)
        body = {'volUrn': kwargs.get('volume_urn')}
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end attach_vol_to_vm()"))


    def stop_vm(self, **kwargs):
        '''
                'stop_vm': ('POST',
                            ('/vms', None, kwargs.get('vm_id'), 'action/stop'),
                            {},
                            {'mode': kwargs.get('mode')},
                            True),
        '''
        LOG.debug(_("[VRM-CINDER] start stop_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/stop'
        new_url = self._generate_url(path)
        body = {'mode': kwargs.get('mode')}
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def _combine_empty_vmConfig(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_empty_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024


        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = []
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] _combine_empty_vmConfig end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_import(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [
            {
                'volumeUrn': volumeUrn,
                'datastoreUrn': datastoreUrn,
                'quantityGB': disk_quantityGB,
                'volType': 0,
                'sequenceNum': kwargs.get('volume_sequence_num'),
                'pciType': 'IDE',
                'volumeUuid': uuid,
                'isThin': thin,
                'isCoverData':True
            }
        ]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_clone(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [
            {
                'datastoreUrn': datastoreUrn,
                'quantityGB': disk_quantityGB,
                'volType': 0,
                'sequenceNum': 1,
                'pciType': 'IDE',
                'volumeUuid': uuid,
                'isThin': thin
            }
        ]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_export(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [
            {
                'sequenceNum': kwargs.get('volume_sequence_num'),
            }
        ]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_os_options(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        osOptions = {
            'osType': 'Windows',
            'osVersion': 26
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return osOptions

    def clone_vm(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''

        LOG.debug(_("[VRM-CINDER] start clone_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('template_id') + '/action/clone'
        new_url = self._generate_url(path)

        linked_clone = kwargs.get('linked_clone')
        if linked_clone is None:
            linked_clone = False
        LOG.debug(_("[VRM-CINDER] start clone_vm()"))
        body = {
            'name': 'cinder-vm-' + kwargs.get('volume_id'),
            'group': 'FSP',
            'description': 'cinder-driver-temp-vm',
            'autoBoot': 'false',
            'isLinkClone': linked_clone,
            'vmConfig': self._combine_vmConfig_4_clone(**kwargs),
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end clone_vm()"))
        return body.get('urn')

    def import_vm_from_glance(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start import_vm_from_glance()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        if CONF.glance_host is None or str(CONF.glance_port) is None \
                or FC_DRIVER_CONF.glance_server_ip is None:
            LOG.error(_("[VRM-CINDER] params is None,"
                        "glance_host: %s; glance_port: %s; glance_ip: %s"),
                      CONF.glance_host, str(CONF.glance_port),
                      FC_DRIVER_CONF.glance_server_ip)
            raise exception.ParameterNotFound(param='glance_host or '
                                                    'glance_port or glance_ip')

        endpoint = CONF.glance_host + ":" + str(CONF.glance_port)
        token = kwargs.get('auth_token')
        serviceIp = FC_DRIVER_CONF.glance_server_ip
        body = {
            'name': 'cinder-vm-' + name,
            'group': 'FSP',
            'description': 'cinder-glance-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'osOptions': self._combine_os_options(**kwargs),
            'protocol': "glance",
            'vmConfig': self._combine_vmConfig_4_import(**kwargs),
            'isTemplate': template,
            'glanceConfig': {
                'imageID': kwargs.get('image_id'),
                'endPoint': endpoint,
                'serverIp': serviceIp,
                'token': token}
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_glance()"))
        return body.get('urn')


    def import_vm_from_uds(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start import_vm_from_uds()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        if FC_DRIVER_CONF.s3_store_access_key_for_cinder is None or \
                FC_DRIVER_CONF.s3_store_secret_key_for_cinder is None:
            LOG.error(_("[VRM-CINDER] some params is None, please check: "
                        "s3_store_access_key_for_cinder, "
                        "s3_store_secret_key_for_cinder"))
            raise exception.ParameterNotFound(param='s3_store_access_key_for_cinder or '
                                                    's3_store_secret_key_for_cinder')

        uds_name = FC_DRIVER_CONF.s3_store_access_key_for_cinder
        uds_password = FC_DRIVER_CONF.s3_store_secret_key_for_cinder
        location = kwargs.get('image_location')
        location = location.split(":")
        if len(location) != 4:
            msg = _('image_location is invalid')
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs.get('image_id'), reason=msg)
        serverIp = location[0].strip()
        port = location[1].strip()
        bucketName = location[2].strip()
        key = location[3].strip()

        body = {
            'name': 'cinder-vm-' + name,
            'group': 'FSP',
            'description': 'cinder-uds-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'osOptions': self._combine_os_options(**kwargs),
            'protocol': "uds",
            'vmConfig': self._combine_vmConfig_4_import(**kwargs),
            'isTemplate': template,
            's3Config': {
                'serverIp': serverIp,
                'port': port,
                'accessKey': uds_name,
                'secretKey': uds_password,
                'bucketName': bucketName,
                'key': key
            }
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_uds()"))
        return body.get('urn')

    def import_vm_from_nfs(self, **kwargs):
        '''
            'import_vm_from_image': ('POST',
                 ('/vms/action/import', None, None, None),
                 {},
                 dict({
                     'name': 'name',
                     'location': kwargs.get('cluster_urn'),
                     'autoBoot': 'false',
                     'url': kwargs.get('url'),
                     'protocol': 'nfs',
                     'vmConfig': {
                         'cpu': {
                             'quantity': 1
                         },
                         'memory': {
                             'quantityMB': 1024
                         },
                         'disks': [
                             {
                                 'pciType': 'IDE',
                                 'datastoreUrn': kwargs.get('ds_urn'),
                                 'quantityGB': kwargs.get('vol_size'),
                                 'volType': 0,
                                 'sequenceNum': 1,
                             },
                         ],
                     },
                     'osOptions': {
                         'osType': 'Windows',
                         'osVersion': 32
                     }
                 }),
                 True),
        '''

        LOG.debug(_("[VRM-CINDER] start import_vm_from_nfs()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        body = \
            {
                'name': 'cinder-vm-' + name,
                'group': 'FSP',
                'description': 'cinder-nfs-vm',
                'autoBoot': 'false',
                'location': kwargs.get("cluster_urn"),
                'osOptions': self._combine_os_options(**kwargs),
                'protocol': "nfs",
                'vmConfig': self._combine_vmConfig_4_import(**kwargs),
                'url': kwargs.get('image_location'),
                'isTemplate': template
            }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_nfs()"))
        return body.get('urn')



    def create_volume_from_extend(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume_from_extend()"))
        image_type = kwargs.get('image_type')

        if image_type == "nfs":
            LOG.debug(_("[VRM-CINDER] start create_volume_from_nfs"))
            vm_urn = self.import_vm_from_nfs(**kwargs)
        elif image_type == 'uds':
            LOG.debug(_("[VRM-CINDER] start create_volume_from_uds"))
            vm_urn = self.import_vm_from_uds(**kwargs)
        else:
            LOG.debug(_("[VRM-CINDER] start create_volume_from_glance"))
            vm_urn = self.import_vm_from_glance(**kwargs)

        vm_id = vm_urn[-10:]
        vm = self.query_vm(vm_id=vm_id)
        vm_config = vm['vmConfig']
        disks = vm_config['disks']
        volume_urn = None
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        for disk in disks:
            if int(disk['sequenceNum']) == int(kwargs['volume_sequence_num']):
                volume_urn = disk['volumeUrn']
                break
        if volume_urn is None:
            msg = (_("[VRM-CINDER] no available disk"))
            LOG.error(msg)
            self.delete_vm(vm_id=vm_id)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'], reason=msg)
        try:
            self.detach_vol_from_vm(vm_id=vm_id, volume_urn=volume_urn)
        except Exception as ex:
            LOG.error(_('detach volume is failed'))
            self.delete_vm(vm_id=vm_id)
            raise ex

        self.delete_vm(vm_id=vm_id)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return volume_urn

    def check_template_status(self,vm_id):
        LOG.debug(_("[VRM-CINDER] start check template status()"))
        uri = self.site_uri + '/vms/'+vm_id+'/competition'
        method = 'GET'
        new_url = self._generate_url(uri)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] template info %s")%body)
        body.get('status')


    def check_template(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        template_id = kwargs.get('template_id')
        vm_name = kwargs.get('vm_name')
        templates = self._get_templates()
        id = None
        for template in templates:
            if template_id is not None:
                urn = template.get('urn')
                id = urn[-10:]
                if id == template_id:
                    LOG.debug(_("[VRM-CINDER] template exists [%s]"), template_id)
                    return id

            if vm_name is not None:
                name = template.get('name')
                if name == vm_name:
                    urn = template.get('urn')
                    id = urn[-10:]
                    LOG.debug(_("[VRM-CINDER] vm is exists [%s]"), vm_name)
                    return id
        return id



    def create_volume_from_template(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume_from_template()"))
        template = kwargs['image_location']
        kwargs['template_id'] = template[-10:]
        is_exist = self.check_template(**kwargs)
        if is_exist is None:
            msg = (_("[VRM-CINDER] no such template %s "), kwargs.get('template_id'))
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'], reason=msg)

        while True:
            template_vm = self.query_vm(vm_id=kwargs['template_id'])
            LOG.debug(_("[VRM-CINDER] template_vm status is %s"), template_vm.get('status'))
            if 'creating' == template_vm.get('status'):
                sleep(10)
            elif 'stopped' == template_vm.get('status'):
                break
            else:
                msg = (_("[VRM-CINDER] template isn't available %s "), kwargs.get('template_id'))
                LOG.error(msg)
                raise exception.ImageUnacceptable(image_id=kwargs['image_id'], reason=msg)

        vm_config = template_vm['vmConfig']
        template_disks = vm_config['disks']
        if len(template_disks) != 1:
            msg = _("template must have one disk")
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],reason=msg)

        vm_urn = self.clone_vm(**kwargs)
        vm_id = vm_urn[-10:]
        vm = self.query_vm(vm_id=vm_id)
        vm_config = vm['vmConfig']
        disks = vm_config['disks']
        volume_urn = None
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        for disk in disks:
            if int(disk['sequenceNum']) == int(kwargs['volume_sequence_num']):
                volume_urn = disk['volumeUrn']
                break
        if volume_urn is None:
            msg = (_("[VRM-CINDER] no available disk"))
            LOG.error(msg)
            self.delete_vm(vm_id=vm_id)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'], reason=msg)
        try:
            self.detach_vol_from_vm(vm_id=vm_id, volume_urn=volume_urn)
        except Exception as ex:
            LOG.error(_("detach volume is failed "))
            self.delete_vm(vm_id=vm_id)
            raise ex

        self.delete_vm(vm_id=vm_id)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return volume_urn

    def create_linkclone_from_template(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_linkclone_from_template()"))
        kwargs['linked_clone'] = True
        return self.create_volume_from_template(**kwargs)

    def create_linkClone_from_extend(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_linkClone_volume()"))
        kwargs['linkClone'] = True
        vm_name = 'cinder-vm-' + kwargs.get('image_id')
        LOG.debug(_("[VRM-CINDER] vm_name is %s"), vm_name)
        kwargs['vm_name'] = vm_name
        vm_id = self.check_template(**kwargs)
        kwargs.pop('vm_name')
        LOG.debug(_("[VRM-CINDER] vm_id is %s"), vm_id)
        image_type = kwargs.get('image_type')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        if 1 < int(kwargs['volume_sequence_num']):
            msg = (_("[VRM-CINDER] volume_sequence_num is %s "), kwargs['volume_sequence_num'])
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'], reason=msg)

        if vm_id is None:
            kwargs["is_template"] = True
            if image_type == 'nfs':
                vm_urn = self.import_vm_from_nfs(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_nfs vm_urn is %s"), vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
            elif image_type == 'uds':
                vm_urn = self.import_vm_from_uds(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_uds vm_urn is %s"), vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
            else:
                vm_urn = self.import_vm_from_glance(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_glance vm_urn is %s"), vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
        else:
            kwargs.pop('linkClone')
            kwargs['image_location'] = vm_id
            return self.create_linkclone_from_template(**kwargs)


    def _get_templates(self, **kwargs):
        '''
        'list_templates': ('GET',
                   ('/vms', None, None, None),
                   {'limit': kwargs.get('limit'),
                    'offset': kwargs.get('offset'),
                    'scope': kwargs.get('scope'),
                    'isTemplate': 'true'
                   },
                   {},
                   False),
        '''

        LOG.debug(_("[VRM-CINDER] start _get_templates()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri

        offset = 0
        templates = []
        while True:
            parames = {
                'limit': self.limit,
                'offset': offset,
                'scope': kwargs.get('scope'),
                'isTemplate': 'true'
            }
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('vms')
                templates += res
                offset += len(res)
                if offset >= total or len(templates) >= total or len(res) < self.limit:
                    break
            else:
                break

        LOG.debug(_("[VRM-CINDER] end ()"))
        return templates

    def create_vm(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''

        LOG.debug(_("[VRM-CINDER] start create_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)

        body = {
            'name': 'cinder-driver-temp-' + kwargs.get('volume_id'),
            'group': 'FSP',
            'description': 'cinder-driver-temp-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'vmConfig': self._combine_empty_vmConfig(**kwargs),
            'osOptions': self._combine_os_options(**kwargs)
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end create_vm()"))
        return body

    def export_vm_to_glance(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_vm_to_glance"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/export'
        new_url = self._generate_url(path)
        if CONF.glance_host is None or str(CONF.glance_port) is None \
                or FC_DRIVER_CONF.glance_server_ip is None:
            LOG.error(_("[VRM-CINDER] params is None,"
                        "glance_host: %s; glance_port: %s; glance_ip: %s"),
                      CONF.glance_host, str(CONF.glance_port),
                      FC_DRIVER_CONF.glance_server_ip)
            raise exception.ParameterNotFound(param='glance_host or '
                                                    'glance_port or glance_ip')

        endpoint = CONF.glance_host + ":" + str(CONF.glance_port)
        token = kwargs.get('auth_token')
        serviceIp = FC_DRIVER_CONF.glance_server_ip
        
        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'format': format,
            'protocol': 'glance',
            'isOverwrite': 'false',
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            'glanceConfig': {
                'imageID': kwargs.get('image_id'),
                'endPoint': endpoint,
                'serverIp': serviceIp,
                'token': token}
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_glance"))
        return body.get('urn')

    def export_vm_to_uds(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_vm_to_uds"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/export'
        new_url = self._generate_url(path)

        if FC_DRIVER_CONF.s3_store_access_key_for_cinder is None \
                or FC_DRIVER_CONF.s3_store_secret_key_for_cinder is None \
                or FC_DRIVER_CONF.uds_port is None or FC_DRIVER_CONF.uds_ip is None \
                or FC_DRIVER_CONF.uds_bucket_name is None:
            LOG.error(_("[VRM-CINDER] some params is None, please check: "
                        "s3_store_access_key_for_cinder, "
                        "s3_store_secret_key_for_cinder, uds_port, uds_ip, uds_bucket_name"))
            raise exception.ParameterNotFound(param='s3_store_access_key_for_cinder '
                                                    'or s3_store_secret_key_for_cinder or'
                                                    'uds_port or uds_serverIp or uds_bucket_name')

        uds_name = FC_DRIVER_CONF.s3_store_access_key_for_cinder
        uds_password = FC_DRIVER_CONF.s3_store_secret_key_for_cinder
        port = FC_DRIVER_CONF.uds_port
        serverIp = FC_DRIVER_CONF.uds_ip
        bucketName = FC_DRIVER_CONF.uds_bucket_name
        key = kwargs.get('image_id')

        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'format': format,
            'protocol': 'uds',
            'isOverwrite': 'false',
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            's3Config': {
                'serverIp': serverIp,
                'port': port,
                'accessKey': uds_name,
                'secretKey': uds_password,
                'bucketName': bucketName,
                'key': key}
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_uds"))
        return body.get('urn')



    def export_vm_to_nfs(self, **kwargs):
        '''
            Post <vm_uri>/<id>/action/export HTTP/1.1
            Host: https://<ip>:<port>
            Content-Type: application/json; charset=UTF-8
            Accept: application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            "name":string,
            "url:string,
            "username":administrator
            "password":string
            }
        '''

        LOG.debug(_("[VRM-CINDER] start export_vm_to_nfs()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/export'
        new_url = self._generate_url(path)

        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'url': kwargs.get('image_url') + '/' + kwargs.get('image_id'),
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            'format': format,
            'protocol': 'nfs',
            'isOverwrite': 'false'
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_nfs()"))
        return body.get('urn')

    def get_volume_sequence_num(self, vm_body, volume_urn):
        volume_sequence_num = 1
        if vm_body is not None:
            vm_uri = vm_body.get('uri')
            volume_body = self.query_vm(vm_id=vm_uri[-10:])
            if volume_body is not None:
                for item in volume_body.get('vmConfig').get('disks'):
                    if item.get('volumeUrn') == volume_urn:
                        volume_sequence_num = item.get("sequenceNum")
        else:
            LOG.debug(_("[VRM-CINDER] vm_body is null)"))
        return volume_sequence_num

    def export_volume_to_image(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_volume_to_image()"))
        vm_body = self.query_vm_volume(**kwargs)
        if vm_body is not None:
            kwargs['volume_sequence_num'] = self.get_volume_sequence_num(vm_body,
                                                                         kwargs.get('volume_urn'))
            vm_uri = vm_body.get('uri')
            kwargs['vm_id'] = vm_uri[-10:]
            LOG.debug(_("[VRM-CINDER] volume is already attached"))
            self.export_attached_volume_to_image(**kwargs)
            LOG.debug(_("[VRM-CINDER] volume_sequence_num %s"), kwargs['volume_sequence_num'])
            return kwargs['volume_sequence_num']

        vm_body = self.create_vm(**kwargs)
        vm_urn = vm_body.get('urn')
        vm_uri = vm_body.get('uri')


        kwargs['vm_id'] = vm_uri[-10:]

        if kwargs.get('shareable') == 'share':
            kwargs['volume_sequence_num'] = 2
        else:
            kwargs['volume_sequence_num'] = 1

        try:
            self.attach_vol_to_vm(**kwargs)
        except Exception as ex:
            LOG.error(_("[VRM-CINDER] attach volume is error "))
            self.delete_vm(**kwargs)
            raise ex
        try:
            self.export_attached_volume_to_image(**kwargs)
        except Exception as ex:
            LOG.error(_("[VRM-CINDER]  export vm is error "))
            self.detach_vol_from_vm(**kwargs)
            self.delete_vm(**kwargs)
            raise ex

        self.detach_vol_from_vm(**kwargs)

        self.delete_vm(**kwargs)

        LOG.debug(_("[VRM-CINDER] end export_volume_to_nfs()"))
        LOG.debug(_("[VRM-CINDER] volume_sequence_num %s"), kwargs['volume_sequence_num'])
        return kwargs['volume_sequence_num']

    def export_attached_volume_to_image(self, **kwargs):
        image_type = kwargs.get('image_type')
        if image_type == 'nfs':
            LOG.debug(_('[VRM-CINDER]  export_vm_to_nfs'))
            self.export_vm_to_nfs(**kwargs)
        elif image_type == 'uds':
            LOG.debug(_('VRM-CINDER]  export_vm_to_uds'))
            self.export_vm_to_uds(**kwargs)
        else:
            LOG.debug(_('VRM-CINDER]  export_vm_to_glance'))
            self.export_vm_to_glance(**kwargs)

        LOG.debug(_("[VRM-CINDER] end export_attached_volume_to_image()"))

    def query_vm_volume(self, **kwargs):
        '''
            URL:https://192.168.106.111:8443/OmsPortal/service/sites/4286080F/vms
            ?scope=urn%3Asites%3A4286080F%3Avolumes%3A137
            &detail=2
        '''

        LOG.debug(_("[VRM-CINDER] start query_vm_volume()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri
        parames = {
            'scope': kwargs.get('volume_urn'),
            'detail': 0
        }
        appendix = self._joined_params(parames)
        new_url = self._generate_url(path, appendix)
        resp, body = self.vrmhttpclient.request(new_url, method)
        total = int(body.get('total') or 0)
        vm = None
        if total >= 1:
            vms = body.get('vms')
            vm = vms[0]
        else:
            LOG.debug(_("[VRM-CINDER] find no vms()"))
        LOG.debug(_("[VRM-CINDER] end query_vm_volume()"))
        return vm


    def migrate_vm_volume(self, **kwargs):
        '''
            Post /<vm_uri>/<vm_id>/action/migratevol HTTP/1.1
            Host: https://<ip>:<port>
            Content-Type: application/json; charset=UTF-8
            Accept: application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            "disks":[
            {
            "volumeUrn":string
            "datastoreUrn":string //urn:sites:1:datastores:1
            }
            ],
            "speed": integer
            }
        '''

        LOG.debug(_("[VRM-CINDER] start migrate_vm_volume()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/migratevol'
        new_url = self._generate_url(path)

        body = {
            "disks": [
                {
                    "volumeUrn": kwargs.get('volume_urn'),
                    "datastoreUrn": kwargs.get('dest_ds_urn'),
                    'migrateType': kwargs.get('migrate_type')
                }
            ],
            "speed": kwargs.get('speed')
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end migrate_vm_volume()"))
        return body.get('urn')
Пример #4
0
 def __init__(self, *args, **kwargs):
     super(VolumeSnapshotProxy, self).__init__()
     LOG.debug(_("[VRM-CINDER] start __init__()"))
     self.task_proxy = TaskProxy()
Пример #5
0
class VolumeProxy(BaseProxy):
    def __init__(self):
        super(VolumeProxy, self).__init__()
        self.task_proxy = TaskProxy()


    def query_volume(self, **kwargs):
        '''
                'query_volume': ('GET',
                                 ('/volumes', kwargs.get(self.RESOURCE_URI), None, kwargs.get('id')),
                                 {'limit': kwargs.get('limit'),
                                  'offset': kwargs.get('offset'),
                                  'scope': kwargs.get('scope')
                                 },
                                 {},
                                 False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volume()"))
        uri = '/volumes'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('id')

        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        return body

    def list_volumes(self, **kwargs):
        '''
                'list_volumes': ('GET',
                                 ('/volumes', kwargs.get(self.RESOURCE_URI), None, kwargs.get('id')),
                                 {'limit': kwargs.get('limit'),
                                  'offset': kwargs.get('offset'),
                                  'scope': kwargs.get('scope')
                                 },
                                 {},
                                 False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volumesnapshot()"))
        uri = '/volumes'
        method = 'GET'
        path = self.site_uri + uri

        offset = 0
        volumes = []
        while True:
            parames = {
                'limit': self.limit,
                'offset': offset,
                'scope': kwargs.get('scope'),
                'uuid':kwargs.get('uuid')
            }
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('volumes')
                volumes += res
                offset += len(res)
                if offset >= total or len(volumes) >= total or len(res) < self.limit:
                    break
            else:
                break

        return volumes


    def create_volume(self, **kwargs):
        '''
                'create_volume': ('POST',
                                  ('/volumes', None, None, None),
                                  {},
                                  {'name': kwargs.get('name'),
                                   'quantityGB': kwargs.get('quantityGB'),
                                   'datastoreUrn': kwargs.get('datastoreUrn'),
                                   'uuid': kwargs.get('uuid'),
                                   'isThin': kwargs.get('isThin'),
                                   'type': kwargs.get('type'),
                                   'indepDisk': kwargs.get('indepDisk'),
                                   'persistentDisk': kwargs.get('persistentDisk'),
                                   'volumeId': kwargs.get('volumeId'),
                                    'snapshotUuid': kwargs.get('snapshotUuid'),
                                   'imageUrl': kwargs.get('imageUrl'),
                                  },
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume()"))
        uri = '/volumes'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'name': kwargs.get('name'),
            'quantityGB': kwargs.get('size'),
            'datastoreUrn': kwargs.get('ds_urn'),
            'uuid': kwargs.get('uuid'),
            'isThin': kwargs.get('is_thin'),
            'type': kwargs.get('type'),
            'indepDisk': kwargs.get('independent')
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        return body

    def delete_volume(self, **kwargs):
        '''
                'delete_volume': ('DELETE',
                                  ('/volumes', kwargs.get(self.RESOURCE_URI), None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_vm()"))
        uri = '/volumes'
        method = 'DELETE'
        path = kwargs.get('volume_uri')
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
            task_uri = body.get('taskUri')
            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] delete volume (%s)"), ex.errorCode)
            if ex.errorCode == "10420004":
                return
            else:
                raise ex

    def clone_volume(self, **kwargs):
        '''
                        'clone_volume': ('POST',
                                 ('/volumes', None, kwargs.get('src_name'), 'action/copyVol'),
                                 {},
                                 {'destinationVolumeID': kwargs.get('dest_name')
                                 },
                                 True),
        '''
        LOG.debug(_("[VRM-CINDER] start clone_volume()"))
        uri = '/volumes'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('src_volume_id') + '/action/copyVol'
        body = {'dstVolUrn': kwargs.get('dest_volume_urn')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)


    def _copy_nfs_image_to_volume(self, **kwargs):
        '''
                'copy_image_to_volume': ('POST',
                                         ('/volumes/imagetovolume', None, None, None),
                                         {},
                                         {
                                             'volumePara': {
                                                 'quantityGB': kwargs.get('volume_size'),
                                                 'urn': kwargs.get('volume_urn')
                                             },
                                             'imagePara': {
                                                 'id': kwargs.get('image_id'),
                                                 'url': kwargs.get('image_location')
                                             },
                                             'location': kwargs.get('cluster_urn'),
                                             'needCreateVolume': False
                                         },
                                         True),
        '''
        LOG.debug(_("[VRM-CINDER] start copy_image_to_volume()"))
        uri = '/volumes/imagetovolume'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'volumePara': {
                'quantityGB': kwargs.get('volume_size'),
                'urn': kwargs.get('volume_urn')
            },
            'imagePara': {
                'id': kwargs.get('image_id'),
                'url': kwargs.get('image_location')
            },
            'location': kwargs.get('cluster_urn'),
            'needCreateVolume': False
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def _copy_volume_to_image(self, **kwargs):
        '''
                'copy_volume_to_image': ('POST',
                                         ('/volumes/volumetoimage', None, None, None),
                                         {},
                                         {
                                             'volumePara': {'urn': kwargs.get('volume_urn'),
                                                            'quantityGB': kwargs.get('volume_size')},
                                             'imagePara': {'id': kwargs.get('image_id'), 'url': kwargs.get('image_url')}
                                         },
                                         True),
        '''

        LOG.debug(_("[VRM-CINDER] start stop_vm()"))
        uri = '/volumes/volumetoimage'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)

        body = {
            'volumePara': {
                'urn': kwargs.get('volume_urn'),
                'quantityGB': kwargs.get('volume_size')},
            'imagePara': {
                'id': kwargs.get('image_id'),
                'url': kwargs.get('image_url')}
        }
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def manage_existing(self, **kwargs):
        '''
                'manage_existing': ('POST',
                                  ('/volumes', None, None, None),
                                  {},
                                  {'name': kwargs.get('name'),
                                   'quantityGB': kwargs.get('quantityGB'),
                                   'datastoreUrn': kwargs.get('datastoreUrn'),
                                   'uuid': kwargs.get('uuid'),
                                   'type': kwargs.get('type'),
                                   'indepDisk': kwargs.get('indepDisk'),
                                   'persistentDisk': kwargs.get('persistentDisk'),
                                   'volumeId': kwargs.get('volumeId'),
                                   'snapshotUuid': kwargs.get('snapshotUuid'),
                                   'imageUrl': kwargs.get('imageUrl'),
                                  },
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume()"))
        uri = '/volumes/registevol'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'name': kwargs.get('name'),
            'quantityGB': kwargs.get('quantityGB'),
            'volInfoUrl': kwargs.get('volInfoUrl'),
            'uuid': kwargs.get('uuid'),
            'type': kwargs.get('type'),
            'maxReadBytes': kwargs.get('maxReadBytes'),
            'maxWriteBytes': kwargs.get('maxWriteBytes'),
            'maxReadRequest': kwargs.get('maxReadRequest'),
            'maxWriteRequest': kwargs.get('maxWriteRequest')}

        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        return body

    def unmanage(self, **kwargs):
        '''
                'unmanage': ('DELETE',
                                  ('/volumes?isOnlyDelDB=1', kwargs.get(self.RESOURCE_URI), None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start unmanage()"))
        method = 'DELETE'
        path = kwargs.get('volume_uri') + '?isOnlyDelDB=1'
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
            task_uri = body.get('taskUri')
            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] unmanage volume (%s)"), ex.errorCode)
            if ex.errorCode == "10420004":
                return
            else:
                raise ex

    def migrate_volume(self, **kwargs):
        '''
            Post <vol_uri>/<volid>/action/migratevol HTTP/1.1
            Host https://<ip>:<port>
            Accept application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            'datastoreUrn':string,
            'speed': integer
            }
        '''
        LOG.debug(_("[VRM-CINDER] start migrate_volume()"))
        uri = '/volumes'
        method = 'POST'
        mig_type = 1

        path = self.site_uri + uri + '/' + kwargs.get('volume_id') + '/action/migratevol'
        body = {'datastoreUrn': kwargs.get('dest_ds_urn'),
                'speed': kwargs.get('speed'),
                'migrateType': kwargs.get('migrate_type')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def modify_volume(self, **kwargs):
        LOG.debug(_("[VRM-CINDER] start modify_volume()"))
        uri = '/volumes'
        method = 'PUT'
        path = self.site_uri + uri + '/' + kwargs.get('volume_id')
        body = {'type': kwargs.get('type')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        if resp.status_code not in (200, 204):
            raise driver_exception.ClientException(101)

    def extend_volume(self,**kwargs):
        '''
                'extend_volume': ('POST',
                                  (kwargs.get('volume_uri'),'/action/expandVol',  None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start extend_volume()"))
        method='POST'
        body = {'size': kwargs.get('size')}
        volume_uri = kwargs.get('volume_uri')

        path =  volume_uri + '/action/expandVol'
        new_url = self._generate_url(path)

        try:
            resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))

            task_uri = body.get('taskUri')

            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] extend volume (%s)"), ex.errorCode)
            raise ex
        except Exception as ex:
            LOG.debug(_("[VRM-CINDER] extend volume (%s)"), ex)
            raise ex
Пример #6
0
 def __init__(self, *args, **kwargs):
     super(VolumeSnapshotProxy, self).__init__()
     LOG.debug(_("[VRM-CINDER] start __init__()"))
     self.task_proxy = TaskProxy()
Пример #7
0
class VolumeSnapshotProxy(BaseProxy):
    def __init__(self, *args, **kwargs):
        super(VolumeSnapshotProxy, self).__init__()
        LOG.debug(_("[VRM-CINDER] start __init__()"))
        self.task_proxy = TaskProxy()

    def query_volumesnapshot(self, **kwargs):
        '''
            'list_volumesnapshot': ('GET',
                                ('/volumesnapshots', None, kwargs.get('uuid'), None),
                                {'limit': kwargs.get('limit'),
                                 'offset': kwargs.get('offset'),
                                 'scope': kwargs.get('scope')
                                },
                                {},
                                False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('uuid')
        body = None
        offset = 0
        datastores = []
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] query snapshot (%s)"), ex.errorCode)
            if ex.errorCode == "10430051":
                return None
            else:
                raise ex
        '''
        error_code = body.get('errorCode')
        if error_code != None:
            if '10430010' == error_code:
                LOG.debug(_("[VRM-CINDER] snapshot not exist"))
                return None
        '''

        return body

    def list_snapshot(self, **kwargs):
        '''
            'list_volumesnapshot': ('GET',
                                ('/volumesnapshots', None, kwargs.get('uuid'), None),
                                {'limit': kwargs.get('limit'),
                                 'offset': kwargs.get('offset'),
                                 'scope': kwargs.get('scope')
                                },
                                {},
                                False),
        '''
        LOG.debug(_("[VRM-CINDER] start list_snapshot()"))
        uri = '/volumesnapshots/queryVolumeSnapshots'
        method = 'GET'
        path = self.site_uri + uri
        body = None
        offset = 0

        snapshots = []
        while True:
            parames = {'limit': self.limit, 'offset': offset}
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('snapshots')
                snapshots += res
                offset += len(res)
                if offset >= total or len(snapshots) >= total or len(
                        res) < self.limit:
                    break
            else:
                break

        return snapshots

    def create_volumesnapshot(self, **kwargs):
        '''
            'create_volumesnapshot': ('POST',
                                  ('/volumesnapshots', None, None, None),
                                  {},
                                  {'volumeUrn': kwargs.get('vol_urn'), 'snapshotUuid': kwargs.get('uuid'),
                                  },
                                  False),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'POST'
        path = self.site_uri + uri
        body = {
            'volumeUrn': kwargs.get('vol_urn'),
            'snapshotUuid': kwargs.get('snapshot_uuid')
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        if task_uri is not None:
            self.task_proxy.wait_task(task_uri=task_uri)
        return body

    def delete_volumesnapshot(self, **kwargs):
        '''
                    'delete_volumesnapshot': ('DELETE',
                                          ('/volumesnapshots', None, None, kwargs.get('id')),
                                          {},
                                          {
                                              'snapshotUuid': kwargs.get('snapshotUuid'),
                                          },
                                          True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'DELETE'
        path = self.site_uri + uri + '/' + kwargs.get('id')
        body = {
            'volumeUrn': kwargs.get('vol_urn'),
            'snapshotUuid': kwargs.get('snapshot_uuid')
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def create_volume_from_snapshot(self, **kwargs):
        '''
            'createvolumefromsnapshot': ('POST',
                                         ('/volumesnapshots', None, "createvol", None),
                                         {},
                                         {'snapshotUuid': kwargs.get('uuid'),
                                          'volumeName': kwargs.get('name'),
                                          'volumeType': normal/share
                                          'volumeUuid': uuid
                                          'snapshotVolumeType': 0/1
                                         },
                                         True),
        '''
        LOG.debug(_("[VRM-CINDER] start createvolumefromsnapshot()"))
        uri = '/volumesnapshots/createvol'
        method = 'POST'
        path = self.site_uri + uri
        snapshotVolumeType = 0
        if str(kwargs.get('full_clone')) == '0':
            snapshotVolumeType = 1
        body = {
            'snapshotUuid': kwargs.get('snapshot_uuid'),
            'volumeName': kwargs.get('volume_name'),
            'volumeType': kwargs.get('type'),
            'volumeUuid': kwargs.get('volume_uuid'),
            'snapshotVolumeType': snapshotVolumeType,
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        return body
Пример #8
0
class VolumeSnapshotProxy(BaseProxy):
    def __init__(self, *args, **kwargs):
        super(VolumeSnapshotProxy, self).__init__()
        LOG.debug(_("[VRM-CINDER] start __init__()"))
        self.task_proxy = TaskProxy()


    def query_volumesnapshot(self, **kwargs):
        '''
            'list_volumesnapshot': ('GET',
                                ('/volumesnapshots', None, kwargs.get('uuid'), None),
                                {'limit': kwargs.get('limit'),
                                 'offset': kwargs.get('offset'),
                                 'scope': kwargs.get('scope')
                                },
                                {},
                                False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('uuid')
        body = None
        offset = 0
        datastores = []
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] query snapshot (%s)"), ex.errorCode)
            if ex.errorCode == "10430051":
                return None
            else:
                raise ex

        '''
        error_code = body.get('errorCode')
        if error_code != None:
            if '10430010' == error_code:
                LOG.debug(_("[VRM-CINDER] snapshot not exist"))
                return None
        '''

        return body

    def list_snapshot(self, **kwargs):
        '''
            'list_volumesnapshot': ('GET',
                                ('/volumesnapshots', None, kwargs.get('uuid'), None),
                                {'limit': kwargs.get('limit'),
                                 'offset': kwargs.get('offset'),
                                 'scope': kwargs.get('scope')
                                },
                                {},
                                False),
        '''
        LOG.debug(_("[VRM-CINDER] start list_snapshot()"))
        uri = '/volumesnapshots/queryVolumeSnapshots'
        method = 'GET'
        path = self.site_uri + uri
        body = None
        offset = 0

        snapshots = []
        while True:
            parames = {
                'limit': self.limit,
               'offset': offset
               }
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('snapshots')
                snapshots += res
                offset += len(res)
                if offset >= total or len(snapshots) >= total or len(res) < self.limit:
                    break
            else:
                break
       
        return snapshots
        
    def create_volumesnapshot(self, **kwargs):
        '''
            'create_volumesnapshot': ('POST',
                                  ('/volumesnapshots', None, None, None),
                                  {},
                                  {'volumeUrn': kwargs.get('vol_urn'), 'snapshotUuid': kwargs.get('uuid'),
                                  },
                                  False),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'POST'
        path = self.site_uri + uri
        body = {
            'volumeUrn': kwargs.get('vol_urn'),
            'snapshotUuid': kwargs.get('snapshot_uuid')
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_uri = body.get('taskUri')
        if task_uri is not None:
            self.task_proxy.wait_task(task_uri=task_uri)
        return body

    def delete_volumesnapshot(self, **kwargs):
        '''
                    'delete_volumesnapshot': ('DELETE',
                                          ('/volumesnapshots', None, None, kwargs.get('id')),
                                          {},
                                          {
                                              'snapshotUuid': kwargs.get('snapshotUuid'),
                                          },
                                          True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_volumesnapshot()"))
        uri = '/volumesnapshots'
        method = 'DELETE'
        path = self.site_uri + uri + '/' + kwargs.get('id')
        body = {
            'volumeUrn': kwargs.get('vol_urn'),
            'snapshotUuid': kwargs.get('snapshot_uuid')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def create_volume_from_snapshot(self, **kwargs):
        '''
            'createvolumefromsnapshot': ('POST',
                                         ('/volumesnapshots', None, "createvol", None),
                                         {},
                                         {'snapshotUuid': kwargs.get('uuid'),
                                          'volumeName': kwargs.get('name'),
                                          'volumeType': normal/share
                                          'volumeUuid': uuid
                                          'snapshotVolumeType': 0/1
                                         },
                                         True),
        '''
        LOG.debug(_("[VRM-CINDER] start createvolumefromsnapshot()"))
        uri = '/volumesnapshots/createvol'
        method = 'POST'
        path = self.site_uri + uri
        snapshotVolumeType = 0
        if str(kwargs.get('full_clone')) == '0':
            snapshotVolumeType = 1
        body = {
            'snapshotUuid': kwargs.get('snapshot_uuid'),
            'volumeName': kwargs.get('volume_name'),
            'volumeType': kwargs.get('type'),
            'volumeUuid': kwargs.get('volume_uuid'),
            'snapshotVolumeType': snapshotVolumeType,
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method, body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        return body
Пример #9
0
 def __init__(self):
     super(VolumeProxy, self).__init__()
     self.task_proxy = TaskProxy()
Пример #10
0
class VolumeProxy(BaseProxy):
    def __init__(self):
        super(VolumeProxy, self).__init__()
        self.task_proxy = TaskProxy()

    def query_volume(self, **kwargs):
        '''
                'query_volume': ('GET',
                                 ('/volumes', kwargs.get(self.RESOURCE_URI), None, kwargs.get('id')),
                                 {'limit': kwargs.get('limit'),
                                  'offset': kwargs.get('offset'),
                                  'scope': kwargs.get('scope')
                                 },
                                 {},
                                 False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volume()"))
        uri = '/volumes'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('id')

        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        return body

    def list_volumes(self, **kwargs):
        '''
                'list_volumes': ('GET',
                                 ('/volumes', kwargs.get(self.RESOURCE_URI), None, kwargs.get('id')),
                                 {'limit': kwargs.get('limit'),
                                  'offset': kwargs.get('offset'),
                                  'scope': kwargs.get('scope')
                                 },
                                 {},
                                 False),
        '''
        LOG.debug(_("[VRM-CINDER] start query_volumesnapshot()"))
        uri = '/volumes'
        method = 'GET'
        path = self.site_uri + uri

        offset = 0
        volumes = []
        while True:
            parames = {
                'limit': self.limit,
                'offset': offset,
                'scope': kwargs.get('scope'),
                'uuid': kwargs.get('uuid')
            }
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('volumes')
                volumes += res
                offset += len(res)
                if offset >= total or len(volumes) >= total or len(
                        res) < self.limit:
                    break
            else:
                break

        return volumes

    def create_volume(self, **kwargs):
        '''
                'create_volume': ('POST',
                                  ('/volumes', None, None, None),
                                  {},
                                  {'name': kwargs.get('name'),
                                   'quantityGB': kwargs.get('quantityGB'),
                                   'datastoreUrn': kwargs.get('datastoreUrn'),
                                   'uuid': kwargs.get('uuid'),
                                   'isThin': kwargs.get('isThin'),
                                   'type': kwargs.get('type'),
                                   'indepDisk': kwargs.get('indepDisk'),
                                   'persistentDisk': kwargs.get('persistentDisk'),
                                   'volumeId': kwargs.get('volumeId'),
                                    'snapshotUuid': kwargs.get('snapshotUuid'),
                                   'imageUrl': kwargs.get('imageUrl'),
                                  },
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume()"))
        uri = '/volumes'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'name': kwargs.get('name'),
            'quantityGB': kwargs.get('size'),
            'datastoreUrn': kwargs.get('ds_urn'),
            'uuid': kwargs.get('uuid'),
            'isThin': kwargs.get('is_thin'),
            'type': kwargs.get('type'),
            'indepDisk': kwargs.get('independent')
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        return body

    def delete_volume(self, **kwargs):
        '''
                'delete_volume': ('DELETE',
                                  ('/volumes', kwargs.get(self.RESOURCE_URI), None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_vm()"))
        uri = '/volumes'
        method = 'DELETE'
        path = kwargs.get('volume_uri')
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
            task_uri = body.get('taskUri')
            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] delete volume (%s)"), ex.errorCode)
            if ex.errorCode == "10420004":
                return
            else:
                raise ex

    def clone_volume(self, **kwargs):
        '''
                        'clone_volume': ('POST',
                                 ('/volumes', None, kwargs.get('src_name'), 'action/copyVol'),
                                 {},
                                 {'destinationVolumeID': kwargs.get('dest_name')
                                 },
                                 True),
        '''
        LOG.debug(_("[VRM-CINDER] start clone_volume()"))
        uri = '/volumes'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'src_volume_id') + '/action/copyVol'
        body = {'dstVolUrn': kwargs.get('dest_volume_urn')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def _copy_nfs_image_to_volume(self, **kwargs):
        '''
                'copy_image_to_volume': ('POST',
                                         ('/volumes/imagetovolume', None, None, None),
                                         {},
                                         {
                                             'volumePara': {
                                                 'quantityGB': kwargs.get('volume_size'),
                                                 'urn': kwargs.get('volume_urn')
                                             },
                                             'imagePara': {
                                                 'id': kwargs.get('image_id'),
                                                 'url': kwargs.get('image_location')
                                             },
                                             'location': kwargs.get('cluster_urn'),
                                             'needCreateVolume': False
                                         },
                                         True),
        '''
        LOG.debug(_("[VRM-CINDER] start copy_image_to_volume()"))
        uri = '/volumes/imagetovolume'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'volumePara': {
                'quantityGB': kwargs.get('volume_size'),
                'urn': kwargs.get('volume_urn')
            },
            'imagePara': {
                'id': kwargs.get('image_id'),
                'url': kwargs.get('image_location')
            },
            'location': kwargs.get('cluster_urn'),
            'needCreateVolume': False
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def _copy_volume_to_image(self, **kwargs):
        '''
                'copy_volume_to_image': ('POST',
                                         ('/volumes/volumetoimage', None, None, None),
                                         {},
                                         {
                                             'volumePara': {'urn': kwargs.get('volume_urn'),
                                                            'quantityGB': kwargs.get('volume_size')},
                                             'imagePara': {'id': kwargs.get('image_id'), 'url': kwargs.get('image_url')}
                                         },
                                         True),
        '''

        LOG.debug(_("[VRM-CINDER] start stop_vm()"))
        uri = '/volumes/volumetoimage'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)

        body = {
            'volumePara': {
                'urn': kwargs.get('volume_urn'),
                'quantityGB': kwargs.get('volume_size')
            },
            'imagePara': {
                'id': kwargs.get('image_id'),
                'url': kwargs.get('image_url')
            }
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def manage_existing(self, **kwargs):
        '''
                'manage_existing': ('POST',
                                  ('/volumes', None, None, None),
                                  {},
                                  {'name': kwargs.get('name'),
                                   'quantityGB': kwargs.get('quantityGB'),
                                   'datastoreUrn': kwargs.get('datastoreUrn'),
                                   'uuid': kwargs.get('uuid'),
                                   'type': kwargs.get('type'),
                                   'indepDisk': kwargs.get('indepDisk'),
                                   'persistentDisk': kwargs.get('persistentDisk'),
                                   'volumeId': kwargs.get('volumeId'),
                                   'snapshotUuid': kwargs.get('snapshotUuid'),
                                   'imageUrl': kwargs.get('imageUrl'),
                                  },
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume()"))
        uri = '/volumes/registevol'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)
        body = {
            'name': kwargs.get('name'),
            'quantityGB': kwargs.get('quantityGB'),
            'volInfoUrl': kwargs.get('volInfoUrl'),
            'uuid': kwargs.get('uuid'),
            'type': kwargs.get('type'),
            'maxReadBytes': kwargs.get('maxReadBytes'),
            'maxWriteBytes': kwargs.get('maxWriteBytes'),
            'maxReadRequest': kwargs.get('maxReadRequest'),
            'maxWriteRequest': kwargs.get('maxWriteRequest')
        }

        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        return body

    def unmanage(self, **kwargs):
        '''
                'unmanage': ('DELETE',
                                  ('/volumes?isOnlyDelDB=1', kwargs.get(self.RESOURCE_URI), None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start unmanage()"))
        method = 'DELETE'
        path = kwargs.get('volume_uri') + '?isOnlyDelDB=1'
        new_url = self._generate_url(path)
        try:
            resp, body = self.vrmhttpclient.request(new_url, method)
            task_uri = body.get('taskUri')
            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] unmanage volume (%s)"), ex.errorCode)
            if ex.errorCode == "10420004":
                return
            else:
                raise ex

    def migrate_volume(self, **kwargs):
        '''
            Post <vol_uri>/<volid>/action/migratevol HTTP/1.1
            Host https://<ip>:<port>
            Accept application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            'datastoreUrn':string,
            'speed': integer
            }
        '''
        LOG.debug(_("[VRM-CINDER] start migrate_volume()"))
        uri = '/volumes'
        method = 'POST'
        mig_type = 1

        path = self.site_uri + uri + '/' + kwargs.get(
            'volume_id') + '/action/migratevol'
        body = {
            'datastoreUrn': kwargs.get('dest_ds_urn'),
            'speed': kwargs.get('speed'),
            'migrateType': kwargs.get('migrate_type')
        }
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)

    def modify_volume(self, **kwargs):
        LOG.debug(_("[VRM-CINDER] start modify_volume()"))
        uri = '/volumes'
        method = 'PUT'
        path = self.site_uri + uri + '/' + kwargs.get('volume_id')
        body = {'type': kwargs.get('type')}
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        if resp.status_code not in (200, 204):
            raise driver_exception.ClientException(101)

    def extend_volume(self, **kwargs):
        '''
                'extend_volume': ('POST',
                                  (kwargs.get('volume_uri'),'/action/expandVol',  None, None),
                                  {},
                                  {},
                                  True),
        '''
        LOG.debug(_("[VRM-CINDER] start extend_volume()"))
        method = 'POST'
        body = {'size': kwargs.get('size')}
        volume_uri = kwargs.get('volume_uri')

        path = volume_uri + '/action/expandVol'
        new_url = self._generate_url(path)

        try:
            resp, body = self.vrmhttpclient.request(new_url,
                                                    method,
                                                    body=json.dumps(body))

            task_uri = body.get('taskUri')

            self.task_proxy.wait_task(task_uri=task_uri)
        except driver_exception.ClientException as ex:
            LOG.debug(_("[VRM-CINDER] extend volume (%s)"), ex.errorCode)
            raise ex
        except Exception as ex:
            LOG.debug(_("[VRM-CINDER] extend volume (%s)"), ex)
            raise ex
Пример #11
0
 def __init__(self, *args, **kwargs):
     super(VmProxy, self).__init__()
     self.task_proxy = TaskProxy()
Пример #12
0
class VmProxy(BaseProxy):
    '''
    VmProxy
    '''
    def __init__(self, *args, **kwargs):
        super(VmProxy, self).__init__()
        self.task_proxy = TaskProxy()

    def query_vm(self, **kwargs):
        '''
        'query_vm': ('GET',
                     ('/vms', None, kwargs.get('vm_id'), None),
                     {},
                     {},
                     False)
        '''
        LOG.debug(_("[VRM-CINDER] start query_vm()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return body

    def query_vm_by_uri(self, **kwargs):
        '''
        'query_vm': ('GET',
                     ('/vms', None, kwargs.get('vm_id'), None),
                     {},
                     {},
                     False)
        '''
        LOG.debug(_("[VRM-CINDER] start query_vm()"))
        method = 'GET'
        path = kwargs.get('vm_uri')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return body

    def delete_vm(self, **kwargs):
        '''
                'delete_vm': ('DELETE',
                              ('/vms', None, kwargs.get('vm_id'), None),
                              {},
                              {},
                              True),
        '''
        LOG.debug(_("[VRM-CINDER] start delete_vm()"))
        uri = '/vms'
        method = 'DELETE'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id')
        new_url = self._generate_url(path)
        resp, body = self.vrmhttpclient.request(new_url, method)
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def detach_vol_from_vm(self, **kwargs):
        '''
                'detach_vol_from_vm': ('POST',
                                       ('/vms', None, kwargs.get('vm_id'), 'action/detachvol'),
                                       {},
                                       {'volUrn': kwargs.get('volUrn')},
                                       True),
        '''
        LOG.debug(_("[VRM-CINDER] start detach_vol_from_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/detachvol'
        new_url = self._generate_url(path)
        body = {'volUrn': kwargs.get('volume_urn')}
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def attach_vol_to_vm(self, **kwargs):
        '''
                'attach_vol_to_vm': ('POST',
                                       ('/vms', None, kwargs.get('vm_id'), 'action/attachvol'),
                                       {},
                                       {'volUrn': kwargs.get('volUrn')},
                                       True),
        '''
        LOG.debug(_("[VRM-CINDER] start attach_vol_to_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/attachvol'
        new_url = self._generate_url(path)
        body = {'volUrn': kwargs.get('volume_urn')}
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end attach_vol_to_vm()"))

    def stop_vm(self, **kwargs):
        '''
                'stop_vm': ('POST',
                            ('/vms', None, kwargs.get('vm_id'), 'action/stop'),
                            {},
                            {'mode': kwargs.get('mode')},
                            True),
        '''
        LOG.debug(_("[VRM-CINDER] start stop_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get('vm_id') + '/action/stop'
        new_url = self._generate_url(path)
        body = {'mode': kwargs.get('mode')}
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_urn_ = body.get('taskUrn')
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end ()"))

    def _combine_empty_vmConfig(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_empty_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024

        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = []
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] _combine_empty_vmConfig end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_import(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [{
            'volumeUrn': volumeUrn,
            'datastoreUrn': datastoreUrn,
            'quantityGB': disk_quantityGB,
            'volType': 0,
            'sequenceNum': kwargs.get('volume_sequence_num'),
            'pciType': 'IDE',
            'volumeUuid': uuid,
            'isThin': thin,
            'isCoverData': True
        }]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_clone(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [{
            'datastoreUrn': datastoreUrn,
            'quantityGB': disk_quantityGB,
            'volType': 0,
            'sequenceNum': 1,
            'pciType': 'IDE',
            'volumeUuid': uuid,
            'isThin': thin
        }]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_vmConfig_4_export(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start _combine_vmConfig ()"))
        cpu_quantity = 2
        mem_quantityMB = 1024
        datastoreUrn = kwargs.get('ds_urn')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        disk_quantityGB = kwargs.get('volume_size')
        link = kwargs.get('linkClone')
        if link:
            uuid = ""
        else:
            uuid = kwargs.get("volume_id")

        thin = kwargs.get('is_thin')
        volumeUrn = kwargs.get('volume_urn')
        cpu = {'quantity': cpu_quantity}
        memory = {'quantityMB': mem_quantityMB}
        disks = [{
            'sequenceNum': kwargs.get('volume_sequence_num'),
        }]
        vmConfigBody = {
            'cpu': cpu,
            'memory': memory,
            'disks': disks,
        }
        LOG.debug(_("[VRM-CINDER] end ()"))
        return vmConfigBody

    def _combine_os_options(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        osOptions = {'osType': 'Windows', 'osVersion': 26}
        LOG.debug(_("[VRM-CINDER] end ()"))
        return osOptions

    def clone_vm(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''

        LOG.debug(_("[VRM-CINDER] start clone_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'template_id') + '/action/clone'
        new_url = self._generate_url(path)

        linked_clone = kwargs.get('linked_clone')
        if linked_clone is None:
            linked_clone = False
        LOG.debug(_("[VRM-CINDER] start clone_vm()"))
        body = {
            'name': 'cinder-vm-' + kwargs.get('volume_id'),
            'group': 'FSP',
            'description': 'cinder-driver-temp-vm',
            'autoBoot': 'false',
            'isLinkClone': linked_clone,
            'vmConfig': self._combine_vmConfig_4_clone(**kwargs),
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end clone_vm()"))
        return body.get('urn')

    def import_vm_from_glance(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start import_vm_from_glance()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        if CONF.glance_host is None or str(CONF.glance_port) is None \
                or FC_DRIVER_CONF.glance_server_ip is None:
            LOG.error(
                _("[VRM-CINDER] params is None,"
                  "glance_host: %s; glance_port: %s; glance_ip: %s"),
                CONF.glance_host, str(CONF.glance_port),
                FC_DRIVER_CONF.glance_server_ip)
            raise exception.ParameterNotFound(param='glance_host or '
                                              'glance_port or glance_ip')

        endpoint = CONF.glance_host + ":" + str(CONF.glance_port)
        token = kwargs.get('auth_token')
        serviceIp = FC_DRIVER_CONF.glance_server_ip
        body = {
            'name': 'cinder-vm-' + name,
            'group': 'FSP',
            'description': 'cinder-glance-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'osOptions': self._combine_os_options(**kwargs),
            'protocol': "glance",
            'vmConfig': self._combine_vmConfig_4_import(**kwargs),
            'isTemplate': template,
            'glanceConfig': {
                'imageID': kwargs.get('image_id'),
                'endPoint': endpoint,
                'serverIp': serviceIp,
                'token': token
            }
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_glance()"))
        return body.get('urn')

    def import_vm_from_uds(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start import_vm_from_uds()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        if FC_DRIVER_CONF.s3_store_access_key_for_cinder is None or \
                FC_DRIVER_CONF.s3_store_secret_key_for_cinder is None:
            LOG.error(
                _("[VRM-CINDER] some params is None, please check: "
                  "s3_store_access_key_for_cinder, "
                  "s3_store_secret_key_for_cinder"))
            raise exception.ParameterNotFound(
                param='s3_store_access_key_for_cinder or '
                's3_store_secret_key_for_cinder')

        uds_name = FC_DRIVER_CONF.s3_store_access_key_for_cinder
        uds_password = FC_DRIVER_CONF.s3_store_secret_key_for_cinder
        location = kwargs.get('image_location')
        location = location.split(":")
        if len(location) != 4:
            msg = _('image_location is invalid')
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs.get('image_id'),
                                              reason=msg)
        serverIp = location[0].strip()
        port = location[1].strip()
        bucketName = location[2].strip()
        key = location[3].strip()

        body = {
            'name': 'cinder-vm-' + name,
            'group': 'FSP',
            'description': 'cinder-uds-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'osOptions': self._combine_os_options(**kwargs),
            'protocol': "uds",
            'vmConfig': self._combine_vmConfig_4_import(**kwargs),
            'isTemplate': template,
            's3Config': {
                'serverIp': serverIp,
                'port': port,
                'accessKey': uds_name,
                'secretKey': uds_password,
                'bucketName': bucketName,
                'key': key
            }
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_uds()"))
        return body.get('urn')

    def import_vm_from_nfs(self, **kwargs):
        '''
            'import_vm_from_image': ('POST',
                 ('/vms/action/import', None, None, None),
                 {},
                 dict({
                     'name': 'name',
                     'location': kwargs.get('cluster_urn'),
                     'autoBoot': 'false',
                     'url': kwargs.get('url'),
                     'protocol': 'nfs',
                     'vmConfig': {
                         'cpu': {
                             'quantity': 1
                         },
                         'memory': {
                             'quantityMB': 1024
                         },
                         'disks': [
                             {
                                 'pciType': 'IDE',
                                 'datastoreUrn': kwargs.get('ds_urn'),
                                 'quantityGB': kwargs.get('vol_size'),
                                 'volType': 0,
                                 'sequenceNum': 1,
                             },
                         ],
                     },
                     'osOptions': {
                         'osType': 'Windows',
                         'osVersion': 32
                     }
                 }),
                 True),
        '''

        LOG.debug(_("[VRM-CINDER] start import_vm_from_nfs()"))
        uri = self.site_uri + '/vms/action/import'
        method = 'POST'
        new_url = self._generate_url(uri)
        link_nfs = kwargs.get('linkClone')
        if link_nfs:
            name = kwargs.get('image_id')
        else:
            name = kwargs.get('volume_id')

        is_template = kwargs.get("is_template")
        if is_template is None:
            template = 'false'
        else:
            template = 'true'

        body = \
            {
                'name': 'cinder-vm-' + name,
                'group': 'FSP',
                'description': 'cinder-nfs-vm',
                'autoBoot': 'false',
                'location': kwargs.get("cluster_urn"),
                'osOptions': self._combine_os_options(**kwargs),
                'protocol': "nfs",
                'vmConfig': self._combine_vmConfig_4_import(**kwargs),
                'url': kwargs.get('image_location'),
                'isTemplate': template
            }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end import_vm_from_nfs()"))
        return body.get('urn')

    def create_volume_from_extend(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume_from_extend()"))
        image_type = kwargs.get('image_type')

        if image_type == "nfs":
            LOG.debug(_("[VRM-CINDER] start create_volume_from_nfs"))
            vm_urn = self.import_vm_from_nfs(**kwargs)
        elif image_type == 'uds':
            LOG.debug(_("[VRM-CINDER] start create_volume_from_uds"))
            vm_urn = self.import_vm_from_uds(**kwargs)
        else:
            LOG.debug(_("[VRM-CINDER] start create_volume_from_glance"))
            vm_urn = self.import_vm_from_glance(**kwargs)

        vm_id = vm_urn[-10:]
        vm = self.query_vm(vm_id=vm_id)
        vm_config = vm['vmConfig']
        disks = vm_config['disks']
        volume_urn = None
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        for disk in disks:
            if int(disk['sequenceNum']) == int(kwargs['volume_sequence_num']):
                volume_urn = disk['volumeUrn']
                break
        if volume_urn is None:
            msg = (_("[VRM-CINDER] no available disk"))
            LOG.error(msg)
            self.delete_vm(vm_id=vm_id)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                              reason=msg)
        try:
            self.detach_vol_from_vm(vm_id=vm_id, volume_urn=volume_urn)
        except Exception as ex:
            LOG.error(_('detach volume is failed'))
            self.delete_vm(vm_id=vm_id)
            raise ex

        self.delete_vm(vm_id=vm_id)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return volume_urn

    def check_template_status(self, vm_id):
        LOG.debug(_("[VRM-CINDER] start check template status()"))
        uri = self.site_uri + '/vms/' + vm_id + '/competition'
        method = 'GET'
        new_url = self._generate_url(uri)
        resp, body = self.vrmhttpclient.request(new_url, method)
        LOG.debug(_("[VRM-CINDER] template info %s") % body)
        body.get('status')

    def check_template(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        template_id = kwargs.get('template_id')
        vm_name = kwargs.get('vm_name')
        templates = self._get_templates()
        id = None
        for template in templates:
            if template_id is not None:
                urn = template.get('urn')
                id = urn[-10:]
                if id == template_id:
                    LOG.debug(_("[VRM-CINDER] template exists [%s]"),
                              template_id)
                    return id

            if vm_name is not None:
                name = template.get('name')
                if name == vm_name:
                    urn = template.get('urn')
                    id = urn[-10:]
                    LOG.debug(_("[VRM-CINDER] vm is exists [%s]"), vm_name)
                    return id
        return id

    def create_volume_from_template(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_volume_from_template()"))
        template = kwargs['image_location']
        kwargs['template_id'] = template[-10:]
        is_exist = self.check_template(**kwargs)
        if is_exist is None:
            msg = (_("[VRM-CINDER] no such template %s "),
                   kwargs.get('template_id'))
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                              reason=msg)

        while True:
            template_vm = self.query_vm(vm_id=kwargs['template_id'])
            LOG.debug(_("[VRM-CINDER] template_vm status is %s"),
                      template_vm.get('status'))
            if 'creating' == template_vm.get('status'):
                sleep(10)
            elif 'stopped' == template_vm.get('status'):
                break
            else:
                msg = (_("[VRM-CINDER] template isn't available %s "),
                       kwargs.get('template_id'))
                LOG.error(msg)
                raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                                  reason=msg)

        vm_config = template_vm['vmConfig']
        template_disks = vm_config['disks']
        if len(template_disks) != 1:
            msg = _("template must have one disk")
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                              reason=msg)

        vm_urn = self.clone_vm(**kwargs)
        vm_id = vm_urn[-10:]
        vm = self.query_vm(vm_id=vm_id)
        vm_config = vm['vmConfig']
        disks = vm_config['disks']
        volume_urn = None
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        for disk in disks:
            if int(disk['sequenceNum']) == int(kwargs['volume_sequence_num']):
                volume_urn = disk['volumeUrn']
                break
        if volume_urn is None:
            msg = (_("[VRM-CINDER] no available disk"))
            LOG.error(msg)
            self.delete_vm(vm_id=vm_id)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                              reason=msg)
        try:
            self.detach_vol_from_vm(vm_id=vm_id, volume_urn=volume_urn)
        except Exception as ex:
            LOG.error(_("detach volume is failed "))
            self.delete_vm(vm_id=vm_id)
            raise ex

        self.delete_vm(vm_id=vm_id)
        LOG.debug(_("[VRM-CINDER] end ()"))
        return volume_urn

    def create_linkclone_from_template(self, **kwargs):
        '''
        create_linkclone_volume

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_linkclone_from_template()"))
        kwargs['linked_clone'] = True
        return self.create_volume_from_template(**kwargs)

    def create_linkClone_from_extend(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start create_linkClone_volume()"))
        kwargs['linkClone'] = True
        vm_name = 'cinder-vm-' + kwargs.get('image_id')
        LOG.debug(_("[VRM-CINDER] vm_name is %s"), vm_name)
        kwargs['vm_name'] = vm_name
        vm_id = self.check_template(**kwargs)
        kwargs.pop('vm_name')
        LOG.debug(_("[VRM-CINDER] vm_id is %s"), vm_id)
        image_type = kwargs.get('image_type')
        if kwargs.get('volume_sequence_num') is None:
            kwargs['volume_sequence_num'] = 1
        if 1 < int(kwargs['volume_sequence_num']):
            msg = (_("[VRM-CINDER] volume_sequence_num is %s "),
                   kwargs['volume_sequence_num'])
            LOG.error(msg)
            raise exception.ImageUnacceptable(image_id=kwargs['image_id'],
                                              reason=msg)

        if vm_id is None:
            kwargs["is_template"] = True
            if image_type == 'nfs':
                vm_urn = self.import_vm_from_nfs(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_nfs vm_urn is %s"),
                          vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
            elif image_type == 'uds':
                vm_urn = self.import_vm_from_uds(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_uds vm_urn is %s"),
                          vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
            else:
                vm_urn = self.import_vm_from_glance(**kwargs)
                kwargs.pop('linkClone')
                LOG.debug(_("[VRM-CINDER] import_vm_from_glance vm_urn is %s"),
                          vm_urn)
                vm_id = vm_urn[-10:]
                kwargs['image_location'] = vm_id
                return self.create_linkclone_from_template(**kwargs)
        else:
            kwargs.pop('linkClone')
            kwargs['image_location'] = vm_id
            return self.create_linkclone_from_template(**kwargs)

    def _get_templates(self, **kwargs):
        '''
        'list_templates': ('GET',
                   ('/vms', None, None, None),
                   {'limit': kwargs.get('limit'),
                    'offset': kwargs.get('offset'),
                    'scope': kwargs.get('scope'),
                    'isTemplate': 'true'
                   },
                   {},
                   False),
        '''

        LOG.debug(_("[VRM-CINDER] start _get_templates()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri

        offset = 0
        templates = []
        while True:
            parames = {
                'limit': self.limit,
                'offset': offset,
                'scope': kwargs.get('scope'),
                'isTemplate': 'true'
            }
            appendix = self._joined_params(parames)
            new_url = self._generate_url(path, appendix)
            resp, body = self.vrmhttpclient.request(new_url, method)
            total = int(body.get('total') or 0)
            if total > 0:
                res = body.get('vms')
                templates += res
                offset += len(res)
                if offset >= total or len(templates) >= total or len(
                        res) < self.limit:
                    break
            else:
                break

        LOG.debug(_("[VRM-CINDER] end ()"))
        return templates

    def create_vm(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''

        LOG.debug(_("[VRM-CINDER] start create_vm()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri
        new_url = self._generate_url(path)

        body = {
            'name': 'cinder-driver-temp-' + kwargs.get('volume_id'),
            'group': 'FSP',
            'description': 'cinder-driver-temp-vm',
            'autoBoot': 'false',
            'location': kwargs.get("cluster_urn"),
            'vmConfig': self._combine_empty_vmConfig(**kwargs),
            'osOptions': self._combine_os_options(**kwargs)
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end create_vm()"))
        return body

    def export_vm_to_glance(self, **kwargs):
        '''
        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_vm_to_glance"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/export'
        new_url = self._generate_url(path)
        if CONF.glance_host is None or str(CONF.glance_port) is None \
                or FC_DRIVER_CONF.glance_server_ip is None:
            LOG.error(
                _("[VRM-CINDER] params is None,"
                  "glance_host: %s; glance_port: %s; glance_ip: %s"),
                CONF.glance_host, str(CONF.glance_port),
                FC_DRIVER_CONF.glance_server_ip)
            raise exception.ParameterNotFound(param='glance_host or '
                                              'glance_port or glance_ip')

        endpoint = CONF.glance_host + ":" + str(CONF.glance_port)
        token = kwargs.get('auth_token')
        serviceIp = FC_DRIVER_CONF.glance_server_ip

        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'format': format,
            'protocol': 'glance',
            'isOverwrite': 'false',
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            'glanceConfig': {
                'imageID': kwargs.get('image_id'),
                'endPoint': endpoint,
                'serverIp': serviceIp,
                'token': token
            }
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_glance"))
        return body.get('urn')

    def export_vm_to_uds(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_vm_to_uds"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/export'
        new_url = self._generate_url(path)

        if FC_DRIVER_CONF.s3_store_access_key_for_cinder is None \
                or FC_DRIVER_CONF.s3_store_secret_key_for_cinder is None \
                or FC_DRIVER_CONF.uds_port is None or FC_DRIVER_CONF.uds_ip is None \
                or FC_DRIVER_CONF.uds_bucket_name is None:
            LOG.error(
                _("[VRM-CINDER] some params is None, please check: "
                  "s3_store_access_key_for_cinder, "
                  "s3_store_secret_key_for_cinder, uds_port, uds_ip, uds_bucket_name"
                  ))
            raise exception.ParameterNotFound(
                param='s3_store_access_key_for_cinder '
                'or s3_store_secret_key_for_cinder or'
                'uds_port or uds_serverIp or uds_bucket_name')

        uds_name = FC_DRIVER_CONF.s3_store_access_key_for_cinder
        uds_password = FC_DRIVER_CONF.s3_store_secret_key_for_cinder
        port = FC_DRIVER_CONF.uds_port
        serverIp = FC_DRIVER_CONF.uds_ip
        bucketName = FC_DRIVER_CONF.uds_bucket_name
        key = kwargs.get('image_id')

        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'format': format,
            'protocol': 'uds',
            'isOverwrite': 'false',
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            's3Config': {
                'serverIp': serverIp,
                'port': port,
                'accessKey': uds_name,
                'secretKey': uds_password,
                'bucketName': bucketName,
                'key': key
            }
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))
        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_uds"))
        return body.get('urn')

    def export_vm_to_nfs(self, **kwargs):
        '''
            Post <vm_uri>/<id>/action/export HTTP/1.1
            Host: https://<ip>:<port>
            Content-Type: application/json; charset=UTF-8
            Accept: application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            "name":string,
            "url:string,
            "username":administrator
            "password":string
            }
        '''

        LOG.debug(_("[VRM-CINDER] start export_vm_to_nfs()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/export'
        new_url = self._generate_url(path)

        format = 'xml' if FC_DRIVER_CONF.export_version == 'v1.2' else 'ovf'
        body = {
            'name': kwargs.get('image_id'),
            'url': kwargs.get('image_url') + '/' + kwargs.get('image_id'),
            'vmConfig': self._combine_vmConfig_4_export(**kwargs),
            'format': format,
            'protocol': 'nfs',
            'isOverwrite': 'false'
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end export_vm_to_nfs()"))
        return body.get('urn')

    def get_volume_sequence_num(self, vm_body, volume_urn):
        volume_sequence_num = 1
        if vm_body is not None:
            vm_uri = vm_body.get('uri')
            volume_body = self.query_vm(vm_id=vm_uri[-10:])
            if volume_body is not None:
                for item in volume_body.get('vmConfig').get('disks'):
                    if item.get('volumeUrn') == volume_urn:
                        volume_sequence_num = item.get("sequenceNum")
        else:
            LOG.debug(_("[VRM-CINDER] vm_body is null)"))
        return volume_sequence_num

    def export_volume_to_image(self, **kwargs):
        '''

        :param kwargs:
        :return:
        '''
        LOG.debug(_("[VRM-CINDER] start export_volume_to_image()"))
        vm_body = self.query_vm_volume(**kwargs)
        if vm_body is not None:
            kwargs['volume_sequence_num'] = self.get_volume_sequence_num(
                vm_body, kwargs.get('volume_urn'))
            vm_uri = vm_body.get('uri')
            kwargs['vm_id'] = vm_uri[-10:]
            LOG.debug(_("[VRM-CINDER] volume is already attached"))
            self.export_attached_volume_to_image(**kwargs)
            LOG.debug(_("[VRM-CINDER] volume_sequence_num %s"),
                      kwargs['volume_sequence_num'])
            return kwargs['volume_sequence_num']

        vm_body = self.create_vm(**kwargs)
        vm_urn = vm_body.get('urn')
        vm_uri = vm_body.get('uri')

        kwargs['vm_id'] = vm_uri[-10:]

        if kwargs.get('shareable') == 'share':
            kwargs['volume_sequence_num'] = 2
        else:
            kwargs['volume_sequence_num'] = 1

        try:
            self.attach_vol_to_vm(**kwargs)
        except Exception as ex:
            LOG.error(_("[VRM-CINDER] attach volume is error "))
            self.delete_vm(**kwargs)
            raise ex
        try:
            self.export_attached_volume_to_image(**kwargs)
        except Exception as ex:
            LOG.error(_("[VRM-CINDER]  export vm is error "))
            self.detach_vol_from_vm(**kwargs)
            self.delete_vm(**kwargs)
            raise ex

        self.detach_vol_from_vm(**kwargs)

        self.delete_vm(**kwargs)

        LOG.debug(_("[VRM-CINDER] end export_volume_to_nfs()"))
        LOG.debug(_("[VRM-CINDER] volume_sequence_num %s"),
                  kwargs['volume_sequence_num'])
        return kwargs['volume_sequence_num']

    def export_attached_volume_to_image(self, **kwargs):
        image_type = kwargs.get('image_type')
        if image_type == 'nfs':
            LOG.debug(_('[VRM-CINDER]  export_vm_to_nfs'))
            self.export_vm_to_nfs(**kwargs)
        elif image_type == 'uds':
            LOG.debug(_('VRM-CINDER]  export_vm_to_uds'))
            self.export_vm_to_uds(**kwargs)
        else:
            LOG.debug(_('VRM-CINDER]  export_vm_to_glance'))
            self.export_vm_to_glance(**kwargs)

        LOG.debug(_("[VRM-CINDER] end export_attached_volume_to_image()"))

    def query_vm_volume(self, **kwargs):
        '''
            URL:https://192.168.106.111:8443/OmsPortal/service/sites/4286080F/vms
            ?scope=urn%3Asites%3A4286080F%3Avolumes%3A137
            &detail=2
        '''

        LOG.debug(_("[VRM-CINDER] start query_vm_volume()"))
        uri = '/vms'
        method = 'GET'
        path = self.site_uri + uri
        parames = {'scope': kwargs.get('volume_urn'), 'detail': 0}
        appendix = self._joined_params(parames)
        new_url = self._generate_url(path, appendix)
        resp, body = self.vrmhttpclient.request(new_url, method)
        total = int(body.get('total') or 0)
        vm = None
        if total >= 1:
            vms = body.get('vms')
            vm = vms[0]
        else:
            LOG.debug(_("[VRM-CINDER] find no vms()"))
        LOG.debug(_("[VRM-CINDER] end query_vm_volume()"))
        return vm

    def migrate_vm_volume(self, **kwargs):
        '''
            Post /<vm_uri>/<vm_id>/action/migratevol HTTP/1.1
            Host: https://<ip>:<port>
            Content-Type: application/json; charset=UTF-8
            Accept: application/json;version=<version>; charset=UTF-8
            X-Auth-Token: <Authen_TOKEN>
            {
            "disks":[
            {
            "volumeUrn":string
            "datastoreUrn":string //urn:sites:1:datastores:1
            }
            ],
            "speed": integer
            }
        '''

        LOG.debug(_("[VRM-CINDER] start migrate_vm_volume()"))
        uri = '/vms'
        method = 'POST'
        path = self.site_uri + uri + '/' + kwargs.get(
            'vm_id') + '/action/migratevol'
        new_url = self._generate_url(path)

        body = {
            "disks": [{
                "volumeUrn": kwargs.get('volume_urn'),
                "datastoreUrn": kwargs.get('dest_ds_urn'),
                'migrateType': kwargs.get('migrate_type')
            }],
            "speed":
            kwargs.get('speed')
        }
        resp, body = self.vrmhttpclient.request(new_url,
                                                method,
                                                body=json.dumps(body))

        task_uri = body.get('taskUri')
        self.task_proxy.wait_task(task_uri=task_uri)
        LOG.debug(_("[VRM-CINDER] end migrate_vm_volume()"))
        return body.get('urn')