mirror of
https://github.com/fusion44/blitz_api.git
synced 2026-08-16 12:20:14 +02:00
feat: make config loading more flexible
If the environment variable BAPI_ENV_PATH is set, the config system will try to read configs from the given path instead of .env in pwd If no file is found .env in pwd will be used as a fallback Env variables will always override settings in .env files.
This commit is contained in:
parent
76b3e5019b
commit
25e4be8441
24 changed files with 444 additions and 235 deletions
|
|
@ -1,11 +1,11 @@
|
|||
import logging
|
||||
import secrets
|
||||
from typing import Dict
|
||||
|
||||
import psutil
|
||||
from decouple import config
|
||||
from fastapi import HTTPException, status
|
||||
from loguru import logger
|
||||
|
||||
from app.api.config import config
|
||||
from app.api.constants import API_VERSION
|
||||
from app.auth.auth_handler import sign_jwt
|
||||
from app.lightning.service import get_ln_info
|
||||
|
|
@ -19,24 +19,25 @@ from app.system.models import (
|
|||
SystemInfo,
|
||||
)
|
||||
|
||||
_SLEEP_TIME = config("gather_hw_info_interval", default=2, cast=float)
|
||||
_CPU_AVG_PERIOD = config("cpu_usage_averaging_period", default=0.5, cast=float)
|
||||
_SLEEP_TIME = config("BAPI_GATHER_HW_INFO_INTERVAL", default=2, cast=float)
|
||||
_CPU_AVG_PERIOD = config("BAPI_CPU_USAGE_AVERAGING_PERIOD", default=0.5, cast=float)
|
||||
_HW_INFO_YIELD_TIME = _SLEEP_TIME + _CPU_AVG_PERIOD
|
||||
|
||||
|
||||
class NativePythonSystem(SystemBase):
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def get_system_info(self) -> SystemInfo:
|
||||
lninfo = await get_ln_info()
|
||||
|
||||
version = config("np_version", default="")
|
||||
version = config("BAPI_NP_VERSION", default="")
|
||||
|
||||
tor_api = config("np_tor_address_api_endpoint", default="")
|
||||
tor_api_docs = config("np_tor_address_api_docs", default="")
|
||||
tor_api = config("BAPI_NP_TOR_ADDRESS_API_ENDPOINT", default="")
|
||||
tor_api_docs = config("BAPI_NP_TOR_ADDRESS_API_DOCS", default="")
|
||||
|
||||
lan_api = config("np_local_address_api_endpoint", default="")
|
||||
lan_api_docs = config("np_local_address_api_docs", default="")
|
||||
lan_api = config("BAPI_NP_LOCAL_ADDRESS_API_ENDPOINT", default="")
|
||||
lan_api_docs = config("BAPI_NP_LOCAL_ADDRESS_API_DOCS", default="")
|
||||
|
||||
ssh_address = config("np_ssh_address", default="")
|
||||
ssh_address = config("BAPI_NP_SSH_ADDRESS", default="")
|
||||
|
||||
return SystemInfo(
|
||||
alias=lninfo.alias,
|
||||
|
|
@ -52,19 +53,26 @@ class NativePythonSystem(SystemBase):
|
|||
chain=lninfo.chains[0].network,
|
||||
)
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def get_system_health(self, verbose: bool) -> SystemHealthInfo:
|
||||
return SystemHealthInfo(healthy=True)
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def shutdown(self, reboot: bool) -> bool:
|
||||
logging.info("Shutdown / reboot not supported in native_python mode.")
|
||||
logger.info("Shutdown / reboot not supported in native_python mode.")
|
||||
return False
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def get_connection_info(self) -> ConnectionInfo:
|
||||
# return an empty connection info object for now
|
||||
return ConnectionInfo()
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def login(self, i: LoginInput) -> Dict[str, str]:
|
||||
matches = secrets.compare_digest(i.password, config("login_password", cast=str))
|
||||
# https://github.com/fusion44/blitz_api/issues/255
|
||||
matches = secrets.compare_digest(
|
||||
i.password, config("BAPI_NATIVE_LOGIN_PASSWORD", cast=str)
|
||||
)
|
||||
if matches:
|
||||
return sign_jwt()
|
||||
|
||||
|
|
@ -72,75 +80,92 @@ class NativePythonSystem(SystemBase):
|
|||
status.HTTP_401_UNAUTHORIZED, detail="Password is incorrect"
|
||||
)
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def change_password(self, type: str, old_password: str, new_password: str):
|
||||
raise NotImplementedError()
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def get_debug_logs_raw(self) -> RawDebugLogData:
|
||||
raise NotImplementedError()
|
||||
|
||||
@logger.catch(exclude=(HTTPException,))
|
||||
async def get_hardware_info(self) -> map:
|
||||
info = {}
|
||||
|
||||
info["cpu_overall_percent"] = psutil.cpu_percent(interval=_CPU_AVG_PERIOD)
|
||||
info["cpu_per_cpu_percent"] = psutil.cpu_percent(
|
||||
interval=_CPU_AVG_PERIOD, percpu=True
|
||||
)
|
||||
try:
|
||||
info["cpu_overall_percent"] = psutil.cpu_percent(interval=_CPU_AVG_PERIOD)
|
||||
info["cpu_per_cpu_percent"] = psutil.cpu_percent(
|
||||
interval=_CPU_AVG_PERIOD, percpu=True
|
||||
)
|
||||
|
||||
v = psutil.virtual_memory()
|
||||
info["vram_total_bytes"] = v.total
|
||||
info["vram_available_bytes"] = v.available
|
||||
info["vram_used_bytes"] = v.used
|
||||
info["vram_usage_percent"] = v.percent
|
||||
v = psutil.virtual_memory()
|
||||
info["vram_total_bytes"] = v.total
|
||||
info["vram_available_bytes"] = v.available
|
||||
info["vram_used_bytes"] = v.used
|
||||
info["vram_usage_percent"] = v.percent
|
||||
|
||||
s = psutil.swap_memory()
|
||||
info["swap_ram_total_bytes"] = s.total
|
||||
info["swap_used_bytes"] = s.used
|
||||
info["swap_usage_bytes"] = s.percent
|
||||
s = psutil.swap_memory()
|
||||
info["swap_ram_total_bytes"] = s.total
|
||||
info["swap_used_bytes"] = s.used
|
||||
info["swap_usage_bytes"] = s.percent
|
||||
|
||||
info["temperatures_celsius"] = psutil.sensors_temperatures()
|
||||
info["boot_time_timestamp"] = psutil.boot_time()
|
||||
info["temperatures_celsius"] = psutil.sensors_temperatures()
|
||||
info["boot_time_timestamp"] = psutil.boot_time()
|
||||
|
||||
disk_io = psutil.disk_io_counters()
|
||||
info["disk_io_read_count"] = disk_io.read_count
|
||||
info["disk_io_write_count"] = disk_io.write_count
|
||||
info["disk_io_read_bytes"] = disk_io.read_bytes
|
||||
info["disk_io_write_bytes"] = disk_io.write_bytes
|
||||
disk_io = psutil.disk_io_counters()
|
||||
info["disk_io_read_count"] = disk_io.read_count
|
||||
info["disk_io_write_count"] = disk_io.write_count
|
||||
info["disk_io_read_bytes"] = disk_io.read_bytes
|
||||
info["disk_io_write_bytes"] = disk_io.write_bytes
|
||||
|
||||
disks = []
|
||||
partitions = psutil.disk_partitions()
|
||||
for partition in partitions:
|
||||
p = {}
|
||||
p["device"] = partition.device
|
||||
p["mountpoint"] = partition.mountpoint
|
||||
p["filesystem_type"] = partition.fstype
|
||||
disks = []
|
||||
partitions = psutil.disk_partitions()
|
||||
for partition in partitions:
|
||||
p = {}
|
||||
p["device"] = partition.device
|
||||
p["mountpoint"] = partition.mountpoint
|
||||
p["filesystem_type"] = partition.fstype
|
||||
|
||||
try:
|
||||
usage = psutil.disk_usage(partition.mountpoint)
|
||||
p["partition_total_bytes"] = usage.total
|
||||
p["partition_used_bytes"] = usage.used
|
||||
p["partition_free_bytes"] = usage.free
|
||||
p["partition_percent"] = usage.percent
|
||||
except PermissionError:
|
||||
continue
|
||||
disks.append(p)
|
||||
info["disks"] = disks
|
||||
try:
|
||||
usage = psutil.disk_usage(partition.mountpoint)
|
||||
p["partition_total_bytes"] = usage.total
|
||||
p["partition_used_bytes"] = usage.used
|
||||
p["partition_free_bytes"] = usage.free
|
||||
p["partition_percent"] = usage.percent
|
||||
except PermissionError:
|
||||
continue
|
||||
disks.append(p)
|
||||
info["disks"] = disks
|
||||
|
||||
nets = []
|
||||
addresses = psutil.net_if_addrs()
|
||||
for name, address in addresses.items():
|
||||
net = {}
|
||||
nets.append(net)
|
||||
net["interface_name"] = name
|
||||
for a in address:
|
||||
if str(a.family) == "AddressFamily.AF_INET":
|
||||
net["address"] = a.address
|
||||
elif str(a.family) == "AddressFamily.AF_PACKET":
|
||||
net["mac_address"] = a.address
|
||||
nets = []
|
||||
addresses = psutil.net_if_addrs()
|
||||
for name, address in addresses.items():
|
||||
net = {}
|
||||
nets.append(net)
|
||||
net["interface_name"] = name
|
||||
for a in address:
|
||||
if str(a.family) == "AddressFamily.AF_INET":
|
||||
net["address"] = a.address
|
||||
elif str(a.family) == "AddressFamily.AF_PACKET":
|
||||
net["mac_address"] = a.address
|
||||
|
||||
net_io = psutil.net_io_counters()
|
||||
info["networks"] = nets
|
||||
info["networks_bytes_sent"] = net_io.bytes_sent
|
||||
info["networks_bytes_received"] = net_io.bytes_recv
|
||||
net_io = psutil.net_io_counters()
|
||||
info["networks"] = nets
|
||||
info["networks_bytes_sent"] = net_io.bytes_sent
|
||||
info["networks_bytes_received"] = net_io.bytes_recv
|
||||
|
||||
except FileNotFoundError:
|
||||
logger.warning("Unable to access /proc/stat to get CPU stats")
|
||||
except OSError as e:
|
||||
logger.warning(
|
||||
f"""Unable to query system: {e}
|
||||
Check if the system is hardened against such calls.
|
||||
For example in Nix you must not harden the following:
|
||||
ProtectProc = "invisible"; // to get HW info
|
||||
ProcSubset = "pid"; // to get HW info
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; // to get network info
|
||||
"""
|
||||
)
|
||||
|
||||
return info
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue