use crate::actors::vnc_tokens_actor::VNC_TOKEN_LIFETIME; use crate::app_config::AppConfig; use crate::constants; use crate::constants::{DISK_NAME_MAX_LEN, DISK_NAME_MIN_LEN, DISK_SIZE_MAX, DISK_SIZE_MIN}; use crate::controllers::{HttpResult, LibVirtReq}; use crate::extractors::local_auth_extractor::LocalAuthEnabled; use crate::libvirt_rest_structures::hypervisor::HypervisorInfo; use crate::nat::nat_hook; use crate::utils::net_utils; use actix_web::{HttpResponse, Responder}; use sysinfo::{Components, Disks, Networks, System}; #[derive(serde::Serialize)] struct StaticConfig { auth_disabled: bool, local_auth_enabled: bool, oidc_auth_enabled: bool, iso_mimetypes: &'static [&'static str], net_mac_prefix: &'static str, builtin_nwfilter_rules: &'static [&'static str], nwfilter_chains: &'static [&'static str], constraints: ServerConstraints, } #[derive(serde::Serialize)] struct LenConstraints { min: usize, max: usize, } #[derive(serde::Serialize)] struct SLenConstraints { min: i64, max: i64, } #[derive(serde::Serialize)] struct ServerConstraints { iso_max_size: usize, vnc_token_duration: u64, vm_name_size: LenConstraints, vm_title_size: LenConstraints, group_id_size: LenConstraints, memory_size: LenConstraints, disk_name_size: LenConstraints, disk_size: LenConstraints, net_name_size: LenConstraints, net_title_size: LenConstraints, net_nat_comment_size: LenConstraints, dhcp_reservation_host_name: LenConstraints, nwfilter_name_size: LenConstraints, nwfilter_comment_size: LenConstraints, nwfilter_priority: SLenConstraints, nwfilter_selectors_count: LenConstraints, api_token_name_size: LenConstraints, api_token_description_size: LenConstraints, api_token_right_path_size: LenConstraints, } pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder { HttpResponse::Ok().json(StaticConfig { auth_disabled: AppConfig::get().unsecure_disable_auth, local_auth_enabled: *local_auth, oidc_auth_enabled: !AppConfig::get().disable_oidc, iso_mimetypes: &constants::ALLOWED_ISO_MIME_TYPES, net_mac_prefix: constants::NET_MAC_ADDR_PREFIX, builtin_nwfilter_rules: &constants::BUILTIN_NETWORK_FILTER_RULES, nwfilter_chains: &constants::NETWORK_CHAINS, constraints: ServerConstraints { iso_max_size: constants::ISO_MAX_SIZE, vnc_token_duration: VNC_TOKEN_LIFETIME, vm_name_size: LenConstraints { min: 2, max: 50 }, vm_title_size: LenConstraints { min: 0, max: 50 }, group_id_size: LenConstraints { min: 3, max: 50 }, memory_size: LenConstraints { min: constants::MIN_VM_MEMORY, max: constants::MAX_VM_MEMORY, }, disk_name_size: LenConstraints { min: DISK_NAME_MIN_LEN, max: DISK_NAME_MAX_LEN, }, disk_size: LenConstraints { min: DISK_SIZE_MIN, max: DISK_SIZE_MAX, }, net_name_size: LenConstraints { min: 2, max: 50 }, net_title_size: LenConstraints { min: 0, max: 50 }, net_nat_comment_size: LenConstraints { min: 0, max: constants::NET_NAT_COMMENT_MAX_SIZE, }, dhcp_reservation_host_name: LenConstraints { min: 2, max: 250 }, nwfilter_name_size: LenConstraints { min: 2, max: 250 }, nwfilter_comment_size: LenConstraints { min: 0, max: 256 }, nwfilter_priority: SLenConstraints { min: -1000, max: 1000, }, nwfilter_selectors_count: LenConstraints { min: 0, max: 1 }, api_token_name_size: LenConstraints { min: constants::API_TOKEN_NAME_MIN_LENGTH, max: constants::API_TOKEN_NAME_MAX_LENGTH, }, api_token_description_size: LenConstraints { min: constants::API_TOKEN_DESCRIPTION_MIN_LENGTH, max: constants::API_TOKEN_DESCRIPTION_MAX_LENGTH, }, api_token_right_path_size: LenConstraints { min: 0, max: constants::API_TOKEN_RIGHT_PATH_MAX_LENGTH, }, }, }) } #[derive(serde::Serialize)] struct ServerInfo { hypervisor: HypervisorInfo, system: System, components: Components, disks: Disks, networks: Networks, } pub async fn server_info(client: LibVirtReq) -> HttpResult { let mut system = System::new(); system.refresh_all(); let mut components = Components::new(); components.refresh(true); let mut disks = Disks::new(); disks.refresh(true); let mut networks = Networks::new(); networks.refresh(true); Ok(HttpResponse::Ok().json(ServerInfo { hypervisor: client.get_info().await?, system, components, disks, networks, })) } #[derive(serde::Serialize)] struct NetworkHookStatus { installed: bool, content: String, path: &'static str, } pub async fn network_hook_status() -> HttpResult { Ok(HttpResponse::Ok().json(NetworkHookStatus { installed: nat_hook::is_installed()?, content: nat_hook::hook_content()?, path: constants::NAT_HOOK_PATH, })) } pub async fn number_vcpus() -> HttpResult { let mut system = System::new(); system.refresh_cpu_all(); let number_cpus = system.cpus().len(); assert_ne!(number_cpus, 0, "Got invlid number of CPU!"); let mut possible_numbers = vec![1]; if number_cpus > 1 { for i in 0..(number_cpus / 2) { possible_numbers.push(2 + 2 * i); } } Ok(HttpResponse::Ok().json(possible_numbers)) } pub async fn networks_list() -> HttpResult { Ok(HttpResponse::Ok().json(net_utils::net_list())) }