async def sr_vdis(cluster_id: str, sr_uuid: str): """Get VDIs by SR""" from API.v1.VDI.serialize import serialize as _vdi_serialize try: session = create_session(cluster_id, get_xen_clusters=Settings.get_xen_clusters()) sr: SR = SR.get_by_uuid(session=session, uuid=sr_uuid) vdis = sr.get_VDIs() if vdis is not None: vdis = await asyncio.gather(*[_vdi_serialize(vdi) for vdi in vdis]) else: pass if sr is not None: ret = dict(success=True, data=vdis) 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 vdi_get_by_uuid(cluster_id: str, vdi_uuid: str): """ Delete SR by UUID """ 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" ) vdi: VDI = VDI.get_by_uuid(session=session, uuid=vdi_uuid) if vdi is not None: ret = dict(success=vdi.destroy()) 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 find_VDI_by_name(cluster_id: str, args: NameArgs): """Find VDI by Name""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) name = args.name vdis = VDI.get_by_name(session=session, name=name) if vdis is not None: __vdis_list = [] for vdi in vdis: __vdis_list.append(await serialize(vdi)) ret = dict(success=True, data=__vdis_list) 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_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 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 vif_list(cluster_id: str): """ Get All from Storage Repos """ 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" ) vifs = VIF.get_all(session=session) __santilized_vifs = [] santilized_vifs = __santilized_vifs.append for vif in vifs: santilized_vifs(serialize(vif)) ret = dict(success=True, data=__santilized_vifs) 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_get_by_uuid(cluster_id: str, vif_uuid: str): """Get VIF by UUID""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vif: VIF = VIF.get_by_uuid(session=session, uuid=vif_uuid) if vif is not None: ret = dict(success=True, data=await serialize(vif)) 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 vif_set_ipv6_by_uuid( cluster_id: str, vif_uuid: str, addresses: IPAddressesModel ): """Set VIF IPv6 by UUID""" try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) vif: VIF = VIF.get_by_uuid(session=session, uuid=vif_uuid) vif.set_allowed_address_v6(addresses.addresses) ret = dict( success=True, ) 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 vbd_list(cluster_id: str, vdi_uuid: str): """ Get VBD by UUID """ 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") vbds = VBD.get_all(session=session) __vbd_list = [] _vbd_list = __vbd_list.append for vbd in vbds: if vbd.get_VDI().get_uuid() == vdi_uuid: _vbd_list(serialize(vbd)) if vbds is not None: ret = dict(success=True, data=__vbd_list) 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_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 sr_scan(cluster_id: str, sr_uuid: str): """ Scan Storage Repository """ 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") sr: SR = SR.get_by_uuid(session=session, uuid=sr_uuid) if sr is not None: sr.scan() ret = dict(success=True) 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_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 guest_get_by_uuid( cluster_id: str = Path(default=None, title="cluster_id", description="Cluster ID"), guest_uuid: str = Path(default=None, title="guest_uuid", description="Guest UUID"), ): """ Get GuestMetrics by UUID """ try: # KeyError Handling 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") guest: GuestMetrics = Host.get_by_uuid(session=session, uuid=guest_uuid) if guest is not None: ret = dict(success=True, data=serialize(guest)) 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 pif_list(cluster_id: str): """Get All PIF from cluster""" try: session = create_session( _id=cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) pifs = PIF.get_all(session=session) __santilized_pifs = await asyncio.gather(*[serialize(pif) for pif in pifs]) ret = dict(success=True, data=__santilized_pifs) 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 vdi_list(cluster_id: str): """Get VDI by UUID""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vdis = VDI.get_all(session=session) __vdi_list = await asyncio.gather(*[serialize(vdi) for vdi in vdis]) if vdis is not None: ret = dict(success=True, data=__vdi_list) 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: 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_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 host_list(cluster_id: str = Path(default=None, title="cluster_id", description="Cluster ID")): """Get All from Existance Host""" try: session = create_session(cluster_id, get_xen_clusters=Settings.get_xen_clusters()) hosts = Host.list_host(session=session) __hosts_list = await asyncio.gather( *[serialize(host) for host in hosts]) ret = dict(success=True, data=__hosts_list) 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 vif_get_qos_speed_by_uuid(cluster_id: str, vif_uuid: str): """ Set VIF QoS Type by UUID """ 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" ) vif: VIF = VIF.get_by_uuid(session=session, uuid=vif_uuid) if vif is not None: ret = dict(success=True, data=vif.get_qos_info()["kbps"]) 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_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)
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 console_get_by_uuid( cluster_id: str, console_uuid: str, ): """Get Console by UUID""" try: pass session = create_session( cluster_id, get_xen_clusters=Settings.get_xen_clusters() ) console: Console = Console.get_by_uuid(session, console_uuid) if console is not None: ret = dict(success=True, data=await serialize(console)) else: ret = dict(success=False) 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 host_get_by_uuid( cluster_id: str = Path(default=None, title="cluster_id", description="Cluster ID"), host_uuid: str = Path(default=None, title="host_uuid", description="Host UUID"), ): """Get Host by UUID""" try: session = create_session(cluster_id, get_xen_clusters=Settings.get_xen_clusters()) host: Host = Host.get_by_uuid(session=session, uuid=host_uuid) if host is not None: ret = dict(success=True, data=await serialize(host)) 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 _vbd_plug(cluster_id: str, vbd_uuid: str): """Plug VBD into VM""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vbd: VBD = VBD.get_by_uuid(session=session, uuid=vbd_uuid) if vbd is not None: ret = dict(success=vbd.plug()) 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 vif_get_qos_type_by_uuid(cluster_id: str, vif_uuid: str, data: QoSTypeArgs): """Set VIF QoS Data by UUID""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vif: VIF = VIF.get_by_uuid(session=session, uuid=vif_uuid) result = True if data.type is not None: vif.set_qos_type(data.type) if data.info is not None: vif.set_qos_info(data.info) ret = dict(success=True, data=result) 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 vif_get_ipv4_by_uuid(cluster_id: str, vif_uuid: str): """Get VIF IPv4 by UUID""" try: session = create_session(_id=cluster_id, get_xen_clusters=Settings.get_xen_clusters()) vif: VIF = VIF.get_by_uuid(session=session, uuid=vif_uuid) ret = dict( success=True, data=dict( address=vif.get_address_v4(), gateway=vif.get_gateway_v4(), ), ) 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_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)