diff --git a/rust/agama-lib/share/profile.schema.json b/rust/agama-lib/share/profile.schema.json index f260bebe39..7a2cde7fa8 100644 --- a/rust/agama-lib/share/profile.schema.json +++ b/rust/agama-lib/share/profile.schema.json @@ -108,6 +108,18 @@ "type": "string" } }, + "dns_searchlist": { + "type": "array", + "items": { + "description": "DNS search domains", + "type": "string", + "additionalProperties": false + } + }, + "ignore_auto_dns": { + "description": "Whether DNS options provided via DHCP are used or not", + "type": "boolean" + }, "wireless": { "type": "object", "title": "Wireless configuration", diff --git a/rust/agama-lib/src/network/proxies.rs b/rust/agama-lib/src/network/proxies.rs index 9e1de983d3..45321da3bf 100644 --- a/rust/agama-lib/src/network/proxies.rs +++ b/rust/agama-lib/src/network/proxies.rs @@ -159,6 +159,18 @@ trait IP { fn nameservers(&self) -> zbus::Result>; #[dbus_proxy(property)] fn set_nameservers(&self, value: &[&str]) -> zbus::Result<()>; + + /// DNS searchlist property + #[dbus_proxy(property)] + fn dns_searchlist(&self) -> zbus::Result>; + #[dbus_proxy(property)] + fn set_dns_searchlist(&self, value: &[&str]) -> zbus::Result<()>; + + /// Ignore auto DNS property + #[dbus_proxy(property)] + fn ignore_auto_dns(&self) -> zbus::Result; + #[dbus_proxy(property)] + fn set_ignore_auto_dns(&self, value: bool) -> zbus::Result<()>; } #[dbus_proxy( diff --git a/rust/agama-lib/src/network/settings.rs b/rust/agama-lib/src/network/settings.rs index 256ed0d055..7ec3be4068 100644 --- a/rust/agama-lib/src/network/settings.rs +++ b/rust/agama-lib/src/network/settings.rs @@ -85,6 +85,10 @@ pub struct NetworkConnection { pub addresses: Vec, #[serde(skip_serializing_if = "Vec::is_empty", default)] pub nameservers: Vec, + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub dns_searchlist: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + pub ignore_auto_dns: Option, #[serde(skip_serializing_if = "Option::is_none")] pub wireless: Option, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/rust/agama-server/src/network/model.rs b/rust/agama-server/src/network/model.rs index 739a7b6c47..bbe2f8668d 100644 --- a/rust/agama-server/src/network/model.rs +++ b/rust/agama-server/src/network/model.rs @@ -585,6 +585,10 @@ impl TryFrom for Connection { connection.status = status; } + if let Some(ignore_auto_dns) = conn.ignore_auto_dns { + connection.ip_config.ignore_auto_dns = ignore_auto_dns; + } + if let Some(wireless_config) = conn.wireless { let config = WirelessConfig::try_from(wireless_config)?; connection.config = config.into(); @@ -597,6 +601,7 @@ impl TryFrom for Connection { connection.ip_config.addresses = conn.addresses; connection.ip_config.nameservers = conn.nameservers; + connection.ip_config.dns_searchlist = conn.dns_searchlist; connection.ip_config.gateway4 = conn.gateway4; connection.ip_config.gateway6 = conn.gateway6; connection.interface = conn.interface; @@ -616,6 +621,8 @@ impl TryFrom for NetworkConnection { let method6 = Some(conn.ip_config.method6.to_string()); let mac_address = (!mac.is_empty()).then_some(mac); let nameservers = conn.ip_config.nameservers; + let dns_searchlist = conn.ip_config.dns_searchlist; + let ignore_auto_dns = Some(conn.ip_config.ignore_auto_dns); let addresses = conn.ip_config.addresses; let gateway4 = conn.ip_config.gateway4; let gateway6 = conn.ip_config.gateway6; @@ -631,6 +638,8 @@ impl TryFrom for NetworkConnection { gateway4, gateway6, nameservers, + dns_searchlist, + ignore_auto_dns, mac_address, interface, addresses, @@ -759,6 +768,9 @@ pub struct IpConfig { pub addresses: Vec, #[serde(skip_serializing_if = "Vec::is_empty")] pub nameservers: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub dns_searchlist: Vec, + pub ignore_auto_dns: bool, pub gateway4: Option, pub gateway6: Option, pub routes4: Option>, diff --git a/rust/agama-server/src/network/nm/dbus.rs b/rust/agama-server/src/network/nm/dbus.rs index b0e66c0b77..b86853a8ad 100644 --- a/rust/agama-server/src/network/nm/dbus.rs +++ b/rust/agama-server/src/network/nm/dbus.rs @@ -297,6 +297,8 @@ fn ip_config_to_ipv4_dbus(ip_config: &IpConfig) -> HashMap<&str, zvariant::Value let mut ipv4_dbus = HashMap::from([ ("address-data", address_data), ("dns-data", dns_data), + ("dns-search", ip_config.dns_searchlist.clone().into()), + ("ignore-auto-dns", ip_config.ignore_auto_dns.into()), ("method", ip_config.method4.to_string().into()), ]); @@ -342,6 +344,8 @@ fn ip_config_to_ipv6_dbus(ip_config: &IpConfig) -> HashMap<&str, zvariant::Value let mut ipv6_dbus = HashMap::from([ ("address-data", address_data), ("dns-data", dns_data), + ("dns-search", ip_config.dns_searchlist.clone().into()), + ("ignore-auto-dns", ip_config.ignore_auto_dns.into()), ("method", ip_config.method6.to_string().into()), ]); @@ -718,6 +722,24 @@ fn ip_config_from_dbus(conn: &OwnedNestedHash) -> Option { ip_config.nameservers.append(&mut servers); } + if let Some(dns_search) = ipv4.get("dns-search") { + let searchlist: Vec = dns_search + .downcast_ref::()? + .iter() + .flat_map(|x| x.downcast_ref::()) + .map(|x| x.to_string()) + .collect(); + for searchdomain in searchlist { + if !ip_config.dns_searchlist.contains(&searchdomain) { + ip_config.dns_searchlist.push(searchdomain); + } + } + } + + if let Some(ignore_auto_dns) = ipv4.get("ignore-auto-dns") { + ip_config.ignore_auto_dns = ignore_auto_dns.try_into().ok()?; + } + if let Some(route_data) = ipv4.get("route-data") { ip_config.routes4 = routes_from_dbus(route_data); } @@ -742,6 +764,24 @@ fn ip_config_from_dbus(conn: &OwnedNestedHash) -> Option { ip_config.nameservers.append(&mut servers); } + if let Some(dns_search) = ipv6.get("dns-search") { + let searchlist: Vec = dns_search + .downcast_ref::()? + .iter() + .flat_map(|x| x.downcast_ref::()) + .map(|x| x.to_string()) + .collect(); + for searchdomain in searchlist { + if !ip_config.dns_searchlist.contains(&searchdomain) { + ip_config.dns_searchlist.push(searchdomain); + } + } + } + + if let Some(ignore_auto_dns) = ipv6.get("ignore-auto-dns") { + ip_config.ignore_auto_dns = ignore_auto_dns.try_into().ok()?; + } + if let Some(route_data) = ipv6.get("route-data") { ip_config.routes6 = routes_from_dbus(route_data); } @@ -1005,6 +1045,11 @@ mod test { "dns-data".to_string(), Value::new(vec!["192.168.0.2"]).to_owned(), ), + ( + "dns-search".to_string(), + Value::new(vec!["suse.com", "example.com"]).to_owned(), + ), + ("ignore-auto-dns".to_string(), Value::new(true).to_owned()), ( "route-data".to_string(), Value::new(route_v4_data).to_owned(), @@ -1037,6 +1082,10 @@ mod test { "dns-data".to_string(), Value::new(vec!["::ffff:c0a8:102"]).to_owned(), ), + ( + "dns-search".to_string(), + Value::new(vec!["suse.com", "suse.de"]).to_owned(), + ), ( "route-data".to_string(), Value::new(route_v6_data).to_owned(), @@ -1081,6 +1130,13 @@ mod test { "::ffff:c0a8:102".parse::().unwrap() ] ); + assert_eq!(ip_config.dns_searchlist.len(), 3); + assert!(ip_config.dns_searchlist.contains(&"suse.com".to_string())); + assert!(ip_config.dns_searchlist.contains(&"suse.de".to_string())); + assert!(ip_config + .dns_searchlist + .contains(&"example.com".to_string())); + assert!(ip_config.ignore_auto_dns); assert_eq!(ip_config.method4, Ipv4Method::Auto); assert_eq!(ip_config.method6, Ipv6Method::Auto); assert_eq!( @@ -1506,6 +1562,7 @@ mod test { next_hop: Some(IpAddr::from_str("2001:db8::1").unwrap()), metric: Some(100), }]), + dns_searchlist: vec!["suse.com".to_string(), "suse.de".to_string()], ..Default::default() }; let mac_address = MacAddress::from_str("FD:CB:A9:87:65:43").unwrap(); @@ -1562,6 +1619,26 @@ mod test { assert!(route4_hashmap.contains_key("metric")); assert_eq!(route4_hashmap["metric"], Value::from(100_u32)); } + let dns_searchlist_array: Array = ipv4_dbus + .get("dns-search") + .unwrap() + .downcast_ref::() + .unwrap() + .try_into() + .unwrap(); + let dns_searchlist: Vec = dns_searchlist_array + .iter() + .flat_map(|x| x.downcast_ref::()) + .map(|x| x.to_string()) + .collect(); + assert_eq!(dns_searchlist.len(), 2); + assert!(dns_searchlist.contains(&"suse.com".to_string())); + assert!(dns_searchlist.contains(&"suse.de".to_string())); + assert!(!ipv4_dbus + .get("ignore-auto-dns") + .unwrap() + .downcast_ref::() + .unwrap()); let ipv6_dbus = conn_dbus.get("ipv6").unwrap(); let gateway6: &str = ipv6_dbus.get("gateway").unwrap().downcast_ref().unwrap(); @@ -1585,5 +1662,25 @@ mod test { assert!(route6_hashmap.contains_key("metric")); assert_eq!(route6_hashmap["metric"], Value::from(100_u32)); } + let dns_searchlist_array: Array = ipv6_dbus + .get("dns-search") + .unwrap() + .downcast_ref::() + .unwrap() + .try_into() + .unwrap(); + let dns_searchlist: Vec = dns_searchlist_array + .iter() + .flat_map(|x| x.downcast_ref::()) + .map(|x| x.to_string()) + .collect(); + assert_eq!(dns_searchlist.len(), 2); + assert!(dns_searchlist.contains(&"suse.com".to_string())); + assert!(dns_searchlist.contains(&"suse.de".to_string())); + assert!(!ipv6_dbus + .get("ignore-auto-dns") + .unwrap() + .downcast_ref::() + .unwrap()); } } diff --git a/rust/package/agama.changes b/rust/package/agama.changes index 0df4850cb2..970368fce3 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Jul 17 11:15:33 UTC 2024 - Jorik Cronenberg + +- Add dns search domains and ignore-auto-dns to network settings + (gh#openSUSE/agama#1330). + ------------------------------------------------------------------- Tue Jul 16 11:56:29 UTC 2024 - Josef Reidinger