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')
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
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
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
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
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')