From 5e7b5c18627613ba4347df65450263fa66136daf Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 27 Aug 2024 15:59:04 +0200 Subject: [PATCH] Allow to set user DNS through API with auto mode Currently it is only possible to set DNS servers when in static mode. However, there are use cases to set DNS servers when in auto mode as well, e.g. if no local DNS server is provided by the DHCP, or the provided DNS turns out to be non-working. --- supervisor/dbus/network/setting/generate.py | 41 ++++++++++++++------- tests/api/test_network.py | 10 ++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/supervisor/dbus/network/setting/generate.py b/supervisor/dbus/network/setting/generate.py index d2825a71a..7c7924ea9 100644 --- a/supervisor/dbus/network/setting/generate.py +++ b/supervisor/dbus/network/setting/generate.py @@ -102,15 +102,8 @@ def get_connection_from_interface( ipv4[CONF_ATTR_IPV4_METHOD] = Variant("s", "auto") elif interface.ipv4setting.method == InterfaceMethod.DISABLED: ipv4[CONF_ATTR_IPV4_METHOD] = Variant("s", "disabled") - else: + elif interface.ipv4setting.method == InterfaceMethod.STATIC: ipv4[CONF_ATTR_IPV4_METHOD] = Variant("s", "manual") - ipv4[CONF_ATTR_IPV4_DNS] = Variant( - "au", - [ - socket.htonl(int(ip_address)) - for ip_address in interface.ipv4setting.nameservers - ], - ) address_data = [] for address in interface.ipv4setting.address: @@ -123,6 +116,19 @@ def get_connection_from_interface( ipv4[CONF_ATTR_IPV4_ADDRESS_DATA] = Variant("aa{sv}", address_data) ipv4[CONF_ATTR_IPV4_GATEWAY] = Variant("s", str(interface.ipv4setting.gateway)) + else: + raise RuntimeError("Invalid IPv4 InterfaceMethod") + + if ( + not interface.ipv4setting + or interface.ipv4setting.method == InterfaceMethod.AUTO + or interface.ipv4setting.method == InterfaceMethod.STATIC + ): + nameservers = interface.ipv4setting.nameservers if interface.ipv4setting else [] + ipv4[CONF_ATTR_IPV4_DNS] = Variant( + "au", + [socket.htonl(int(ip_address)) for ip_address in nameservers], + ) conn[CONF_ATTR_IPV4] = ipv4 @@ -134,12 +140,8 @@ def get_connection_from_interface( ipv6[CONF_ATTR_IPV6_METHOD] = Variant("s", "auto") elif interface.ipv6setting.method == InterfaceMethod.DISABLED: ipv6[CONF_ATTR_IPV6_METHOD] = Variant("s", "link-local") - else: + elif interface.ipv4setting.method == InterfaceMethod.STATIC: ipv6[CONF_ATTR_IPV6_METHOD] = Variant("s", "manual") - ipv6[CONF_ATTR_IPV6_DNS] = Variant( - "aay", - [ip_address.packed for ip_address in interface.ipv6setting.nameservers], - ) address_data = [] for address in interface.ipv6setting.address: @@ -152,6 +154,19 @@ def get_connection_from_interface( ipv6[CONF_ATTR_IPV6_ADDRESS_DATA] = Variant("aa{sv}", address_data) ipv6[CONF_ATTR_IPV6_GATEWAY] = Variant("s", str(interface.ipv6setting.gateway)) + else: + raise RuntimeError("Invalid IPv6 InterfaceMethod") + + if ( + not interface.ipv6setting + or interface.ipv6setting.method == InterfaceMethod.AUTO + or interface.ipv6setting.method == InterfaceMethod.STATIC + ): + nameservers = interface.ipv6setting.nameservers if interface.ipv6setting else [] + ipv6[CONF_ATTR_IPV6_DNS] = Variant( + "aay", + [ip_address.packed for ip_address in nameservers], + ) conn[CONF_ATTR_IPV6] = ipv6 diff --git a/tests/api/test_network.py b/tests/api/test_network.py index 5b5f60945..5b0309957 100644 --- a/tests/api/test_network.py +++ b/tests/api/test_network.py @@ -251,8 +251,14 @@ async def test_api_network_vlan( "autoconnect": Variant("b", True), "uuid": connection["connection"]["uuid"], } - assert connection["ipv4"] == {"method": Variant("s", "auto")} - assert connection["ipv6"] == {"method": Variant("s", "auto")} + assert connection["ipv4"] == { + "method": Variant("s", "auto"), + "dns": Variant("au", []), + } + assert connection["ipv6"] == { + "method": Variant("s", "auto"), + "dns": Variant("aay", []), + } assert connection["vlan"] == { "id": Variant("u", 1), "parent": Variant("s", "0c23631e-2118-355c-bbb0-8943229cb0d6"),