async def serialize(vm: VM): record = vm.get_record() return dict( name=record["name_label"], bios=record["bios_strings"], power=record["power_state"], description=record["name_description"], uuid=record["uuid"], vCPUs=record["VCPUs_at_startup"], memory=vm.get_memory(), )
def get_vm(self): from XenGarden.VM import VM try: vm = self.session.xenapi.VIF.get_VM(self.vif) vm = VM(self.session, vm) vm.get_uuid() return vm except Failure as xenapi_error: if xenapi_error.details[0] == "HANDLE_INVALID": return None else: raise xenapi_error
async def get_cd_eject(cluster_id: str, vm_uuid: str): try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: new_vbd = vm.get_CD() if new_vbd is not None: success = new_vbd.eject() ret = dict(success=success) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_set_name(cluster_id: str, vm_uuid: str, args: NameArgs): """ Set Instance (VM/Template) Name """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=_vm.set_name(args.name)) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_info(cluster_id: str, vm_uuid: str): """Get an Info of VM or Template""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: ret = dict(success=True, data=await serialize(vm)) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def get_first_vif(cluster_id: str, vm_uuid: str, url_after: str = ""): """Redirect To First Instance VIFs""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) vif = None try: vif = vm.get_VIF() except Exception: session.xenapi.session.logout() raise HTTPException( status_code=404, detail=f"VM {vm_uuid} does not have VIF Interface") vif_uuid = vif.get_uuid() session.xenapi.session.logout() return RedirectResponse(f"/v1/{cluster_id}/vif/{vif_uuid}{url_after}") except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
def get_VM(self): """ get VM attached to the specified VBD """ try: from XenGarden.VM import VM vm = self.session.xenapi.VBD.get_VM(self.vbd) vm = VM(self.session, vm) vm.get_uuid() return vm except Failure as xenapi_error: if xenapi_error.details[0] == "HANDLE_INVALID": return None else: raise xenapi_error
async def vm_consoles(cluster_id: str, vm_uuid: str): """Get all consoles are available to the VM""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) consoles = vm.get_consoles() __consoleList = [] for console in consoles: __consoleList.append(_console_serialize(console)) ret = dict(success=True, data=__consoleList) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_set_vCPU(cluster_id: str, vm_uuid: str, args: VCpuArgs): """Set VM vCPU count""" try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=_vm.set_vCPUs(args.vCPU_count)) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException( status_code=500, detail=xenapi_failure_jsonify(xenapi_error) ) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_get_memory(cluster_id: str, vm_uuid: str): """Get VM Memory (needs troubleshooting)""" try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=True, data=_vm.get_memory()) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException( status_code=500, detail=xenapi_failure_jsonify(xenapi_error) ) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_consoles(cluster_id: str, vm_uuid: str): """ Get all consoles are available to the VM """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: consoles = vm.get_consoles() __consoleList = [] consoleList = __consoleList.append for console in consoles: consoleList(_console_serialize(console)) ret = dict(success=True, data=__consoleList) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def get_cd(cluster_id: str, vm_uuid: str, url_after: str = ""): from XenGarden.VBD import VBD try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) vbd: VBD = vm.get_CD() vbd_uuid = vbd.get_uuid() session.xenapi.session.logout() return RedirectResponse( url=f"/v1/{cluster_id}/vbd/{vbd_uuid}{url_after}") except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_set_vCPU_inurl(cluster_id: str, vm_uuid: str, vCPU_count: int): """ Set VM vCPU count """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=_vm.set_vCPUs(vCPU_count)) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_shutdown(cluster_id: str, vm_uuid: str): """Shutdown VM, can return false if the system does not support ACPI shutdown. System powerstate must be checked beforehand""" try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) except KeyError as key_error: raise HTTPException( status_code=400, detail=f"{key_error} is not a valid path" ) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=_vm.shutdown()) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_get_metadata(cluster_id: str, vm_uuid: str): """Get Instance (VM/Template) Metadata""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) ret = dict( success=True, data={ "name": _vm.get_name(), "description": _vm.get_description() }, ) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_console(cluster_id: str, vm_uuid: str, url_after: str = ""): """Get the first console of the VM""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) consoles: Console = vm.get_consoles() if len(consoles) == 0: raise HTTPException( status_code=404, detail=f"Console doesn't exist on VM {vm_uuid}", ) console: Console = consoles[0] console_uuid = console.get_uuid() return RedirectResponse( url=f"/v1/{cluster_id}/console/{console_uuid}{url_after}") except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_set_platform_property_byname_inurl( cluster_id: str, vm_uuid: str, name: str, var: str ): """ Set Instance (VM/Template) Platform Property by Name """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) except KeyError as key_error: raise HTTPException( status_code=400, detail=f"{key_error} is not a valid path" ) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: data = {name: var} ret = dict(success=vm.set_platform(data)) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_power(cluster_id: str, vm_uuid: str): """ Get VM's power status, Can be "Paused", "Halted", "Running" """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) except KeyError as key_error: raise HTTPException( status_code=400, detail=f"{key_error} is not a valid path" ) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if _vm is not None: ret = dict(success=True, data=_vm.get_power_state()) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_clone(cluster_id: str, vm_uuid: str, args: CloneArgs): """Clone Instance (VM/Template)""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) new_vm = await _vm.clone(args.name) if new_vm is not None: if args.provision: await new_vm.provision() new_vm_uuid = new_vm.get_uuid() ret = Response( "", status_code=302, headers={"Location": f"/v1/{cluster_id}/vm/{new_vm_uuid}"}, ) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def template_list(cluster_id: str): """Gets Templates available on Xen Server""" try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) vms = VM.list_templates(session=session) __sat = [] for vm in vms: __sat.append(await serialize(vm)) ret = dict(success=True, data=__sat) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException( status_code=500, detail=xenapi_failure_jsonify(xenapi_error) ) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_vif(cluster_id: str, vm_uuid: str): """ Show Instnace VIFs """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: new_vif = vm.get_VIF() if new_vif is not None: ret = dict(success=True, data=_vif_serialize(new_vif)) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_list(cluster_id: str): """ Gets VMs available on Xen Server """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vms = VM.list_vm(session=session) __sat = [] sat = __sat.append for vm in vms: sat(serialize(vm)) ret = dict(success=True, data=__sat) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_guest(cluster_id: str, vm_uuid: str): """ Get VM Guest Info """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: ret = dict(success=True, data=_guest_serialize(vm.get_guest_metrics())) else: session.xenapi.session.logout() ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_clone_inurl(cluster_id: str, vm_uuid: str, clone_name: str): """ Clone Instance (VM/Template) """ try: new_vm = None try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") _vm: VM = VM.get_by_uuid(session, vm_uuid) if _vm is not None: new_vm = _vm.clone(clone_name) if new_vm is not None: ret = dict(success=True, data=serialize(new_vm)) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
def serialize(vm: VM): return dict( name=vm.get_name(), bios=vm.get_bios_strings(), power=vm.get_power_state(), description=vm.get_description(), uuid=vm.get_uuid(), vCPUs=vm.get_vCPUs(), memory=vm.get_memory(), )
async def get_cd_insert_inurl(cluster_id: str, vm_uuid: str, vdi_uuid: str): try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: new_vbd = vm.get_CD() if new_vbd is not None: try: from XenGarden.VDI import VDI except ModuleNotFoundError as e: raise HTTPException(status_code=500, detail=e.name) from API.v1.VDI.serialize import serialize as _vdi_serialize vdi: VDI = VDI.get_by_uuid(session=session, uuid=vdi_uuid) if vdi is not None: success = new_vbd.insert(vdi) if success: ret = dict(success=success, data=_vdi_serialize(vdi)) else: ret = dict(success=success) else: ret = dict(success=False) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vif_set_qos_speed_by_vm(cluster_id: str, vm_uuid: str, speed: str): """ Set VIF QoS Speed by VM """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: vif = vm.get_VIF() try: speedNum = int(speed) except ValueError: return dict(success=False) if speedNum <= 0: a = vif.set_qos_type("") b = vif.set_qos_info({}) ret = dict(success=a and b) else: if vif is not None: if vif.get_qos_type() != "ratelimit": vif.set_qos_type("ratelimit") ret = dict(success=vif.set_qos_info(dict(kbps=speed))) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_vbds(cluster_id: str, vm_uuid: str): """ Show Instance VBDs """ try: try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) except KeyError as key_error: raise HTTPException(status_code=400, detail=f"{key_error} is not a valid path") vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) if vm is not None: newVBDs = vm.get_VBDs() __vbd_serialized = [] vbd_serialized = __vbd_serialized.append if newVBDs is not None: for vbd in newVBDs: if vbd is not None: vbd_serialized(_vbd_serialize(vbd)) print(__vbd_serialized) ret = dict(success=True, data=__vbd_serialized) else: ret = dict(success=False) else: ret = dict(success=False) session.xenapi.session.logout() return ret except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def instance_get_bios(cluster_id: str, vm_uuid: str): """Get Instance (VM/Template) BIOS""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) bios_strings = vm.get_bios_strings() session.xenapi.session.logout() return dict(success=True, data=bios_strings) except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)
async def vm_delete(cluster_id: str, vm_uuid: str): """Delete VM""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) _vm: VM = VM.get_by_uuid(session=session, uuid=vm_uuid) ret = dict(success=await _vm.delete()) session.xenapi.session.logout() return ret except Failure as xenapi_error: raise HTTPException(status_code=500, detail=xenapi_failure_jsonify(xenapi_error)) except Fault as xml_rpc_error: raise HTTPException( status_code=int(xml_rpc_error.faultCode), detail=xml_rpc_error.faultString, ) except RemoteDisconnected as rd_error: raise HTTPException(status_code=500, detail=rd_error.strerror)