diff --git a/rust/agama-server/src/network/model.rs b/rust/agama-server/src/network/model.rs index 2871cd806f..1bad95d5e1 100644 --- a/rust/agama-server/src/network/model.rs +++ b/rust/agama-server/src/network/model.rs @@ -6,7 +6,7 @@ use crate::network::error::NetworkStateError; use agama_lib::network::types::{BondMode, DeviceType, SSID}; use cidr::IpInet; use serde::Serialize; -use serde_with::{serde_as, DisplayFromStr}; +use serde_with::{serde_as, skip_serializing_none, DisplayFromStr}; use std::{ collections::HashMap, default::Default, @@ -373,11 +373,13 @@ mod tests { #[derive(Debug, Clone, Serialize)] pub struct Device { pub name: String, + #[serde(rename = "type")] pub type_: DeviceType, } /// Represents an availble network connection. #[serde_as] +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Serialize)] pub struct Connection { pub id: String, @@ -566,11 +568,14 @@ pub enum Status { Removed, } +#[skip_serializing_none] #[derive(Default, Debug, PartialEq, Clone, Serialize)] pub struct IpConfig { pub method4: Ipv4Method, pub method6: Ipv6Method, + #[serde(skip_serializing_if = "Vec::is_empty")] pub addresses: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] pub nameservers: Vec, pub gateway4: Option, pub gateway6: Option, @@ -578,11 +583,16 @@ pub struct IpConfig { pub routes6: Option>, } +#[skip_serializing_none] #[derive(Debug, Default, PartialEq, Clone, Serialize)] pub struct MatchConfig { + #[serde(skip_serializing_if = "Vec::is_empty")] pub driver: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] pub interface: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] pub path: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] pub kernel: Vec, } @@ -675,7 +685,9 @@ impl From for zbus::fdo::Error { #[derive(Debug, PartialEq, Clone, Serialize)] pub struct IpRoute { pub destination: IpInet, + #[serde(skip_serializing_if = "Option::is_none")] pub next_hop: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub metric: Option, } @@ -744,11 +756,16 @@ pub struct WirelessConfig { pub mode: WirelessMode, #[serde_as(as = "DisplayFromStr")] pub ssid: SSID, + #[serde(skip_serializing_if = "Option::is_none")] pub password: Option, pub security: SecurityProtocol, + #[serde(skip_serializing_if = "Option::is_none")] pub band: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub channel: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub bssid: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub wep_security: Option, pub hidden: bool, } @@ -852,6 +869,7 @@ impl TryFrom<&str> for SecurityProtocol { pub struct WEPSecurity { pub auth_alg: WEPAuthAlg, pub wep_key_type: WEPKeyType, + #[serde(skip_serializing_if = "Vec::is_empty")] pub keys: Vec, pub wep_key_index: u32, } @@ -993,15 +1011,22 @@ impl TryFrom for BondConfig { #[derive(Debug, Default, PartialEq, Clone, Serialize)] pub struct BridgeConfig { pub stp: bool, + #[serde(skip_serializing_if = "Option::is_none")] pub priority: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub forward_delay: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub hello_time: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub max_age: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub ageing_time: Option, } #[derive(Debug, Default, PartialEq, Clone, Serialize)] pub struct BridgePortConfig { + #[serde(skip_serializing_if = "Option::is_none")] pub priority: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub path_cost: Option, } diff --git a/rust/agama-server/src/network/system.rs b/rust/agama-server/src/network/system.rs index 7637df44f8..2fb3838a60 100644 --- a/rust/agama-server/src/network/system.rs +++ b/rust/agama-server/src/network/system.rs @@ -80,7 +80,7 @@ impl NetworkSystem { tx.send(conn.cloned()).unwrap(); } Action::GetConnections(tx) => { - tx.send(self.state.connections.clone()); + tx.send(self.state.connections.clone()).unwrap(); } Action::GetConnectionPath(uuid, tx) => { let tree = self.tree.lock().await; @@ -105,7 +105,7 @@ impl NetworkSystem { tx.send(path).unwrap(); } Action::GetDevices(tx) => { - tx.send(self.state.devices.clone()); + tx.send(self.state.devices.clone()).unwrap(); } Action::GetDevicesPaths(tx) => { let tree = self.tree.lock().await; diff --git a/rust/agama-server/src/network/web.rs b/rust/agama-server/src/network/web.rs index c5f91f45f1..e63134a38d 100644 --- a/rust/agama-server/src/network/web.rs +++ b/rust/agama-server/src/network/web.rs @@ -71,7 +71,7 @@ pub async fn network_service(events: EventsSender) -> Router { .with_state(state) } -#[utoipa::path(get, path = "/devices", responses( +#[utoipa::path(get, path = "/network/devices", responses( (status = 200, description = "List of devices", body = Vec) ))] async fn devices(State(state): State) -> Json> { @@ -87,7 +87,7 @@ async fn devices(State(state): State) -> Json> { Json(devices) } -#[utoipa::path(get, path = "/connections", responses( +#[utoipa::path(get, path = "/network/connections", responses( (status = 200, description = "List of known connections", body = Vec) ))] async fn connections(State(state): State) -> Json> {