Fixes issues with managing wireless interfaces (#2015)

* Fixes issues with managing wireless interfaces

* Add test

* Add back fixture
This commit is contained in:
Joakim Sørensen 2020-09-04 20:58:37 +02:00 committed by GitHub
parent f43b4e9e24
commit 25ea80e169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 6 deletions

View File

@ -240,6 +240,7 @@ ATTR_SNAPSHOT_EXCLUDE = "snapshot_exclude"
ATTR_SNAPSHOTS = "snapshots"
ATTR_SOURCE = "source"
ATTR_SQUASH = "squash"
ATTR_SSID = "ssid"
ATTR_SSL = "ssl"
ATTR_STAGE = "stage"
ATTR_STARTUP = "startup"

View File

@ -19,6 +19,8 @@ DBUS_OBJECT_HOSTNAME = "/org/freedesktop/hostname1"
DBUS_OBJECT_NM = "/org/freedesktop/NetworkManager"
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
DBUS_ATTR_802_WIRELESS = "802-11-wireless"
DBUS_ATTR_802_WIRELESS_SECURITY = "802-11-wireless-security"
DBUS_ATTR_ACTIVE_CONNECTIONS = "ActiveConnections"
DBUS_ATTR_ADDRESS_DATA = "AddressData"
DBUS_ATTR_BOOT_SLOT = "BootSlot"

View File

@ -60,3 +60,11 @@ class NetworkDevice:
ip4_address: int = attr.ib()
device_type: int = attr.ib()
real: bool = attr.ib()
@attr.s
class WirelessProperties:
"""WirelessProperties object for Network Manager."""
properties: dict = attr.ib()
security: dict = attr.ib()

View File

@ -4,6 +4,8 @@ from typing import Optional
from ...const import ATTR_ADDRESS, ATTR_IPV4, ATTR_METHOD, ATTR_PREFIX
from ...utils.gdbus import DBus
from ..const import (
DBUS_ATTR_802_WIRELESS,
DBUS_ATTR_802_WIRELESS_SECURITY,
DBUS_ATTR_ADDRESS_DATA,
DBUS_ATTR_CONNECTION,
DBUS_ATTR_DEFAULT,
@ -23,6 +25,7 @@ from ..const import (
DBUS_NAME_IP4CONFIG,
DBUS_NAME_NM,
DBUS_OBJECT_BASE,
ConnectionType,
)
from .configuration import (
AddressData,
@ -30,6 +33,7 @@ from .configuration import (
NetworkAttributes,
NetworkDevice,
NetworkSettings,
WirelessProperties,
)
@ -44,6 +48,7 @@ class NetworkConnection(NetworkAttributes):
self._settings: Optional[NetworkSettings] = None
self._ip4_config: Optional[IpConfiguration] = None
self._device: Optional[NetworkDevice]
self._wireless: Optional[WirelessProperties] = None
self.primary: bool = False
@property
@ -81,6 +86,13 @@ class NetworkConnection(NetworkAttributes):
"""Return the uuid of the connection."""
return self._properties[DBUS_ATTR_UUID]
@property
def wireless(self) -> str:
"""Return wireless properties if any."""
if self.type != ConnectionType.WIRELESS:
return None
return self._wireless
@property
def state(self) -> int:
"""
@ -119,6 +131,11 @@ class NetworkConnection(NetworkAttributes):
),
)
self._wireless = WirelessProperties(
data.get(DBUS_ATTR_802_WIRELESS, {}),
data.get(DBUS_ATTR_802_WIRELESS_SECURITY, {}),
)
self._device = NetworkDevice(
device,
device_data.get(DBUS_ATTR_DEVICE_INTERFACE),

View File

@ -4,6 +4,7 @@ from ..const import (
DBUS_NAME_CONNECTION_ACTIVE,
DBUS_NAME_NM,
DBUS_OBJECT_BASE,
ConnectionType,
InterfaceMethod,
)
from ..payloads.generate import interface_update_payload
@ -49,7 +50,7 @@ class NetworkInterface:
return self.connection.ip4_config.address_data.prefix
@property
def type(self) -> str:
def type(self) -> ConnectionType:
"""Return the interface type."""
return self.connection.type

View File

@ -3,8 +3,8 @@ from pathlib import Path
import jinja2
from ...const import ATTR_ADDRESS, ATTR_DNS, ATTR_METHOD, ATTR_PREFIX
from ..const import InterfaceMethod
from ...const import ATTR_ADDRESS, ATTR_DNS, ATTR_METHOD, ATTR_PREFIX, ATTR_SSID
from ..const import ConnectionType, InterfaceMethod
from ..network.utils import ip2int
INTERFACE_UPDATE_TEMPLATE: Path = (
@ -31,4 +31,15 @@ def interface_update_payload(interface, **kwargs) -> str:
kwargs[ATTR_ADDRESS] = kwargs[ATTR_ADDRESS].split("/")[0]
kwargs[ATTR_METHOD] = InterfaceMethod.MANUAL
if interface.type == ConnectionType.WIRELESS:
kwargs[ATTR_SSID] = ", ".join(
[
f"0x{x}"
for x in interface.connection.wireless.properties[ATTR_SSID]
.encode()
.hex(",")
.split(",")
]
)
return template.render(interface=interface, options=kwargs)

View File

@ -23,4 +23,18 @@
'gateway': <'{{ options.get("gateway", interface.gateway) }}'>
}
{% endif %}
{% if interface.type == "802-11-wireless" %}
,
'802-11-wireless':
{
'security': <'802-11-wireless-security'>,
'ssid': <[byte {{ options.ssid }}]>
},
'802-11-wireless-security':
{
'auth-alg': <'{{ interface.connection.wireless.security['auth-alg'] }}'>,
'key-mgmt': <'{{ interface.connection.wireless.security['key-mgmt'] }}'>
}
{% endif %}
}

View File

@ -1,12 +1,13 @@
"""Test interface update payload."""
import pytest
from supervisor.dbus.const import ConnectionType
from supervisor.dbus.payloads.generate import interface_update_payload
from supervisor.utils.gdbus import DBus
@pytest.mark.asyncio
async def test_interface_update_payload(network_interface):
async def test_interface_update_payload_ethernet(network_interface):
"""Test interface update payload."""
data = interface_update_payload(network_interface, **{"method": "auto"})
assert DBus.parse_gvariant(data)["ipv4"]["method"] == "auto"
@ -17,3 +18,18 @@ async def test_interface_update_payload(network_interface):
assert DBus.parse_gvariant(data)["ipv4"]["method"] == "manual"
assert DBus.parse_gvariant(data)["ipv4"]["address-data"][0]["address"] == "1.1.1.1"
assert DBus.parse_gvariant(data)["ipv4"]["dns"] == [16843009, 16777217]
@pytest.mark.asyncio
async def test_interface_update_payload_wireless(network_interface):
"""Test interface update payload."""
network_interface.connection._properties["Type"] = ConnectionType.WIRELESS
data = interface_update_payload(network_interface, **{"method": "auto"})
assert DBus.parse_gvariant(data)["ipv4"]["method"] == "auto"
data = interface_update_payload(
network_interface, **{"address": "1.1.1.1", "dns": ["1.1.1.1", "1.0.0.1"]}
)
assert DBus.parse_gvariant(data)["ipv4"]["method"] == "manual"
assert DBus.parse_gvariant(data)["ipv4"]["address-data"][0]["address"] == "1.1.1.1"
assert DBus.parse_gvariant(data)["802-11-wireless"]["ssid"] == "NETT"

View File

@ -1 +1 @@
({'connection': {'id': <'Wired connection 1'>, 'permissions': <@as []>, 'timestamp': <uint64 1598125548>, 'type': <'802-3-ethernet'>, 'uuid': <'0c23631e-2118-355c-bbb0-8943229cb0d6'>}, 'ipv4': {'address-data': <[{'address': <'192.168.2.148'>, 'prefix': <uint32 24>}]>, 'addresses': <[[uint32 2483202240, 24, 16951488]]>, 'dns': <[uint32 16951488]>, 'dns-search': <@as []>, 'gateway': <'192.168.2.1'>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@aau []>}, 'ipv6': {'address-data': <@aa{sv} []>, 'addresses': <@a(ayuay) []>, 'dns': <@aay []>, 'dns-search': <@as []>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@a(ayuayu) []>}, 'proxy': {}, '802-3-ethernet': {'auto-negotiate': <false>, 'mac-address-blacklist': <@as []>, 's390-options': <@a{ss} {}>}},)
({'connection': {'id': <'Wired connection 1'>, 'permissions': <@as []>, 'timestamp': <uint64 1598125548>, 'type': <'802-3-ethernet'>, 'uuid': <'0c23631e-2118-355c-bbb0-8943229cb0d6'>}, 'ipv4': {'address-data': <[{'address': <'192.168.2.148'>, 'prefix': <uint32 24>}]>, 'addresses': <[[uint32 2483202240, 24, 16951488]]>, 'dns': <[uint32 16951488]>, 'dns-search': <@as []>, 'gateway': <'192.168.2.1'>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@aau []>}, 'ipv6': {'address-data': <@aa{sv} []>, 'addresses': <@a(ayuay) []>, 'dns': <@aay []>, 'dns-search': <@as []>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@a(ayuayu) []>}, 'proxy': {}, '802-3-ethernet': {'auto-negotiate': <false>, 'mac-address-blacklist': <@as []>, 's390-options': <@a{ss} {}>}, '802-11-wireless': {'ssid': <[byte 0x4e, 0x45, 0x54, 0x54]>}},)

View File

@ -1 +1 @@
({'connection': {'id': <'Wired connection 1'>, 'permissions': <@as []>, 'timestamp': <uint64 1598125548>, 'type': <'802-3-ethernet'>, 'uuid': <'0c23631e-2118-355c-bbb0-8943229cb0d6'>}, 'ipv4': {'address-data': <[{'address': <'192.168.2.148'>, 'prefix': <uint32 24>}]>, 'addresses': <[[uint32 2483202240, 24, 16951488]]>, 'dns': <[uint32 16951488]>, 'dns-search': <@as []>, 'gateway': <'192.168.2.1'>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@aau []>}, 'ipv6': {'address-data': <@aa{sv} []>, 'addresses': <@a(ayuay) []>, 'dns': <@aay []>, 'dns-search': <@as []>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@a(ayuayu) []>}, 'proxy': {}, '802-3-ethernet': {'auto-negotiate': <false>, 'mac-address-blacklist': <@as []>, 's390-options': <@a{ss} {}>}},)
({'connection': {'id': <'Wired connection 1'>, 'permissions': <@as []>, 'timestamp': <uint64 1598125548>, 'type': <'802-3-ethernet'>, 'uuid': <'0c23631e-2118-355c-bbb0-8943229cb0d6'>}, 'ipv4': {'address-data': <[{'address': <'192.168.2.148'>, 'prefix': <uint32 24>}]>, 'addresses': <[[uint32 2483202240, 24, 16951488]]>, 'dns': <[uint32 16951488]>, 'dns-search': <@as []>, 'gateway': <'192.168.2.1'>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@aau []>}, 'ipv6': {'address-data': <@aa{sv} []>, 'addresses': <@a(ayuay) []>, 'dns': <@aay []>, 'dns-search': <@as []>, 'method': <'auto'>, 'route-data': <@aa{sv} []>, 'routes': <@a(ayuayu) []>}, 'proxy': {}, '802-3-ethernet': {'auto-negotiate': <false>, 'mac-address-blacklist': <@as []>, 's390-options': <@a{ss} {}>}, '802-11-wireless': {'ssid': <[byte 0x4e, 0x45, 0x54, 0x54]>}},)