Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unsupported message if no systemd-resolved #3487

Merged
merged 2 commits into from Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 74 additions & 2 deletions supervisor/dbus/const.py
@@ -1,11 +1,13 @@
"""Constants for DBUS."""
from enum import Enum
from enum import Enum, IntEnum
from socket import AF_INET, AF_INET6

DBUS_NAME_HAOS = "io.hass.os"
DBUS_NAME_HOSTNAME = "org.freedesktop.hostname1"
DBUS_NAME_LOGIND = "org.freedesktop.login1"
DBUS_NAME_NM = "org.freedesktop.NetworkManager"
DBUS_NAME_RAUC = "de.pengutronix.rauc"
DBUS_NAME_RESOLVED = "org.freedesktop.resolve1"
DBUS_NAME_SYSTEMD = "org.freedesktop.systemd1"
DBUS_NAME_TIMEDATE = "org.freedesktop.timedate1"

Expand All @@ -24,6 +26,7 @@
DBUS_IFACE_IP6CONFIG = "org.freedesktop.NetworkManager.IP6Config"
DBUS_IFACE_NM = "org.freedesktop.NetworkManager"
DBUS_IFACE_RAUC_INSTALLER = "de.pengutronix.rauc.Installer"
DBUS_IFACE_RESOLVED_MANAGER = "org.freedesktop.resolve1.Manager"
DBUS_IFACE_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection"
DBUS_IFACE_SYSTEMD_MANAGER = "org.freedesktop.systemd1.Manager"
DBUS_IFACE_TIMEDATE = "org.freedesktop.timedate1"
Expand All @@ -43,6 +46,7 @@
DBUS_OBJECT_HOSTNAME = "/org/freedesktop/hostname1"
DBUS_OBJECT_LOGIND = "/org/freedesktop/login1"
DBUS_OBJECT_NM = "/org/freedesktop/NetworkManager"
DBUS_OBJECT_RESOLVED = "/org/freedesktop/resolve1"
DBUS_OBJECT_SETTINGS = "/org/freedesktop/NetworkManager/Settings"
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
DBUS_OBJECT_TIMEDATE = "/org/freedesktop/timedate1"
Expand All @@ -52,19 +56,33 @@
DBUS_ATTR_ACTIVE_CONNECTIONS = "ActiveConnections"
DBUS_ATTR_ADDRESS_DATA = "AddressData"
DBUS_ATTR_BOOT_SLOT = "BootSlot"
DBUS_ATTR_CACHE_STATISTICS = "CacheStatistics"
DBUS_ATTR_CHASSIS = "Chassis"
DBUS_ATTR_COMPATIBLE = "Compatible"
DBUS_ATTR_CONFIGURATION = "Configuration"
DBUS_ATTR_CONNECTION = "Connection"
DBUS_ATTR_CONNECTION_ENABLED = "ConnectivityCheckEnabled"
DBUS_ATTR_CURRENT_DEVICE = "CurrentDevice"
DBUS_ATTR_CURRENT_DNS_SERVER = "CurrentDNSServer"
DBUS_ATTR_CURRENT_DNS_SERVER_EX = "CurrentDNSServerEx"
DBUS_ATTR_DEFAULT = "Default"
DBUS_ATTR_DEPLOYMENT = "Deployment"
DBUS_ATTR_DEVICE_INTERFACE = "Interface"
DBUS_ATTR_DEVICE_TYPE = "DeviceType"
DBUS_ATTR_DEVICES = "Devices"
DBUS_ATTR_DIAGNOSTICS = "Diagnostics"
DBUS_ATTR_DNS = "DNS"
DBUS_ATTR_DNS_EX = "DNSEx"
DBUS_ATTR_DNS_OVER_TLS = "DNSOverTLS"
DBUS_ATTR_DNS_STUB_LISTENER = "DNSStubListener"
DBUS_ATTR_DNSSEC = "DNSSEC"
DBUS_ATTR_DNSSEC_NEGATIVE_TRUST_ANCHORS = "DNSSECNegativeTrustAnchors"
DBUS_ATTR_DNSSEC_STATISTICS = "DNSSECStatistics"
DBUS_ATTR_DNSSEC_SUPPORTED = "DNSSECSupported"
DBUS_ATTR_DOMAINS = "Domains"
DBUS_ATTR_DRIVER = "Driver"
DBUS_ATTR_FALLBACK_DNS = "FallbackDNS"
DBUS_ATTR_FALLBACK_DNS_EX = "FallbackDNSEx"
DBUS_ATTR_FINISH_TIMESTAMP = "FinishTimestamp"
DBUS_ATTR_FIRMWARE_TIMESTAMP_MONOTONIC = "FirmwareTimestampMonotonic"
DBUS_ATTR_FREQUENCY = "Frequency"
Expand All @@ -76,11 +94,13 @@
DBUS_ATTR_KERNEL_RELEASE = "KernelRelease"
DBUS_ATTR_KERNEL_TIMESTAMP_MONOTONIC = "KernelTimestampMonotonic"
DBUS_ATTR_LAST_ERROR = "LastError"
DBUS_ATTR_LLMNR = "LLMNR"
DBUS_ATTR_LLMNR_HOSTNAME = "LLMNRHostname"
DBUS_ATTR_LOADER_TIMESTAMP_MONOTONIC = "LoaderTimestampMonotonic"
DBUS_ATTR_LOCALRTC = "LocalRTC"
DBUS_ATTR_MANAGED = "Managed"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_MULTICAST_DNS = "MulticastDNS"
DBUS_ATTR_NAMESERVER_DATA = "NameserverData"
DBUS_ATTR_NAMESERVERS = "Nameservers"
DBUS_ATTR_NTP = "NTP"
Expand All @@ -89,6 +109,7 @@
DBUS_ATTR_OPERATION = "Operation"
DBUS_ATTR_PARSER_VERSION = "ParserVersion"
DBUS_ATTR_PRIMARY_CONNECTION = "PrimaryConnection"
DBUS_ATTR_RESOLV_CONF_MODE = "ResolvConfMode"
DBUS_ATTR_RCMANAGER = "RcManager"
DBUS_ATTR_SSID = "Ssid"
DBUS_ATTR_STATE = "State"
Expand All @@ -97,6 +118,7 @@
DBUS_ATTR_STRENGTH = "Strength"
DBUS_ATTR_TIMEUSEC = "TimeUSec"
DBUS_ATTR_TIMEZONE = "Timezone"
DBUS_ATTR_TRANSACTION_STATISTICS = "TransactionStatistics"
DBUS_ATTR_TYPE = "Type"
DBUS_ATTR_USERSPACE_TIMESTAMP_MONOTONIC = "UserspaceTimestampMonotonic"
DBUS_ATTR_UUID = "Uuid"
Expand Down Expand Up @@ -176,3 +198,53 @@ class WirelessMethodType(int, Enum):
INFRASTRUCTURE = 2
ACCESSPOINT = 3
MESH = 4


class DNSAddressFamily(IntEnum):
"""Address family for DNS server."""

INET = AF_INET
INET6 = AF_INET6


class MulticastProtocolEnabled(str, Enum):
"""Multicast protocol enabled or resolve."""

YES = "yes"
NO = "no"
RESOLVE = "resolve"


class DNSOverTLSEnabled(str, Enum):
"""DNS over TLS enabled."""

YES = "yes"
NO = "no"
OPPORTUNISTIC = "opportunistic"


class DNSSECValidation(str, Enum):
"""DNSSEC validation enforced."""

YES = "yes"
NO = "no"
ALLOW_DOWNGRADE = "allow-downgrade"


class DNSStubListenerEnabled(str, Enum):
"""DNS stub listener enabled."""

YES = "yes"
NO = "no"
TCP_ONLY = "tcp"
UDP_ONLY = "udp"


class ResolvConfMode(str, Enum):
"""Resolv.conf management mode."""

FOREIGN = "foreign"
MISSING = "missing"
STATIC = "static"
STUB = "stub"
UPLINK = "uplink"
8 changes: 8 additions & 0 deletions supervisor/dbus/manager.py
Expand Up @@ -9,6 +9,7 @@
from .logind import Logind
from .network import NetworkManager
from .rauc import Rauc
from .resolved import Resolved
from .systemd import Systemd
from .timedate import TimeDate

Expand All @@ -29,6 +30,7 @@ def __init__(self, coresys: CoreSys) -> None:
self._network: NetworkManager = NetworkManager()
self._agent: OSAgent = OSAgent()
self._timedate: TimeDate = TimeDate()
self._resolved: Resolved = Resolved()

@property
def systemd(self) -> Systemd:
Expand Down Expand Up @@ -65,6 +67,11 @@ def timedate(self) -> TimeDate:
"""Return the timedate interface."""
return self._timedate

@property
def resolved(self) -> Resolved:
"""Return the resolved interface."""
return self._resolved

async def load(self) -> None:
"""Connect interfaces to D-Bus."""
if not SOCKET_DBUS.exists():
Expand All @@ -81,6 +88,7 @@ async def load(self) -> None:
self.timedate,
self.network,
self.rauc,
self.resolved,
]
for dbus in dbus_loads:
_LOGGER.info("Load dbus interface %s", dbus.name)
Expand Down
188 changes: 188 additions & 0 deletions supervisor/dbus/resolved.py
@@ -0,0 +1,188 @@
"""D-Bus interface for systemd-resolved."""
from __future__ import annotations

import logging
from typing import Any

from ..exceptions import DBusError, DBusInterfaceError
from ..utils.dbus import DBus
from .const import (
DBUS_ATTR_CACHE_STATISTICS,
DBUS_ATTR_CURRENT_DNS_SERVER,
DBUS_ATTR_CURRENT_DNS_SERVER_EX,
DBUS_ATTR_DNS,
DBUS_ATTR_DNS_EX,
DBUS_ATTR_DNS_OVER_TLS,
DBUS_ATTR_DNS_STUB_LISTENER,
DBUS_ATTR_DNSSEC,
DBUS_ATTR_DNSSEC_NEGATIVE_TRUST_ANCHORS,
DBUS_ATTR_DNSSEC_STATISTICS,
DBUS_ATTR_DNSSEC_SUPPORTED,
DBUS_ATTR_DOMAINS,
DBUS_ATTR_FALLBACK_DNS,
DBUS_ATTR_FALLBACK_DNS_EX,
DBUS_ATTR_LLMNR,
DBUS_ATTR_LLMNR_HOSTNAME,
DBUS_ATTR_MULTICAST_DNS,
DBUS_ATTR_RESOLV_CONF_MODE,
DBUS_ATTR_TRANSACTION_STATISTICS,
DBUS_IFACE_RESOLVED_MANAGER,
DBUS_NAME_RESOLVED,
DBUS_OBJECT_RESOLVED,
DNSAddressFamily,
DNSOverTLSEnabled,
DNSSECValidation,
DNSStubListenerEnabled,
MulticastProtocolEnabled,
ResolvConfMode,
)
from .interface import DBusInterface, dbus_property
from .utils import dbus_connected

_LOGGER: logging.Logger = logging.getLogger(__name__)


class Resolved(DBusInterface):
"""Handle D-Bus interface for systemd-resolved."""

name = DBUS_NAME_RESOLVED

def __init__(self):
"""Initialize Properties."""
self.properties: dict[str, Any] = {}

async def connect(self):
"""Connect to D-Bus."""
try:
self.dbus = await DBus.connect(DBUS_NAME_RESOLVED, DBUS_OBJECT_RESOLVED)
except DBusError:
_LOGGER.warning("Can't connect to systemd-resolved.")
except DBusInterfaceError:
_LOGGER.warning(
"Host has no systemd-resolved support. DNS will not work correctly."
)

@property
@dbus_property
def cache_statistics(self) -> tuple[int, int, int] | None:
"""Return current cache entries and hits and misses since last reset."""
return self.properties[DBUS_ATTR_CACHE_STATISTICS]

@property
@dbus_property
def current_dns_server(
self,
) -> list[tuple[int, DNSAddressFamily, bytes]] | None:
"""Return current DNS server."""
return self.properties[DBUS_ATTR_CURRENT_DNS_SERVER]

@property
@dbus_property
def current_dns_server_ex(
self,
) -> list[tuple[int, DNSAddressFamily, bytes, int, str]] | None:
"""Return current DNS server including port and server name."""
return self.properties[DBUS_ATTR_CURRENT_DNS_SERVER_EX]

@property
@dbus_property
def dns(self) -> list[tuple[int, DNSAddressFamily, bytes]] | None:
"""Return DNS servers in use."""
return self.properties[DBUS_ATTR_DNS]

@property
@dbus_property
def dns_ex(self) -> list[tuple[int, DNSAddressFamily, bytes, int, str]] | None:
"""Return DNS servers in use including port and server name."""
return self.properties[DBUS_ATTR_DNS_EX]

@property
@dbus_property
def dns_over_tls(self) -> DNSOverTLSEnabled | None:
"""Return DNS over TLS enabled."""
return self.properties[DBUS_ATTR_DNS_OVER_TLS]

@property
@dbus_property
def dns_stub_listener(self) -> DNSStubListenerEnabled | None:
"""Return DNS stub listener enabled on port 53."""
return self.properties[DBUS_ATTR_DNS_STUB_LISTENER]

@property
@dbus_property
def dnssec(self) -> DNSSECValidation | None:
"""Return DNSSEC validation enforced."""
return self.properties[DBUS_ATTR_DNSSEC]

@property
@dbus_property
def dnssec_negative_trust_anchors(self) -> list[str] | None:
"""Return DNSSEC negative trust anchors."""
return self.properties[DBUS_ATTR_DNSSEC_NEGATIVE_TRUST_ANCHORS]

@property
@dbus_property
def dnssec_statistics(self) -> tuple[int, int, int, int] | None:
"""Return Secure, insecure, bogus, and indeterminate DNSSEC validations since last reset."""
return self.properties[DBUS_ATTR_DNSSEC_STATISTICS]

@property
@dbus_property
def dnssec_supported(self) -> bool | None:
"""Return DNSSEC enabled and selected DNS servers support it."""
return self.properties[DBUS_ATTR_DNSSEC_SUPPORTED]

@property
@dbus_property
def domains(self) -> list[tuple[int, str, bool]] | None:
"""Return search and routing domains in use."""
return self.properties[DBUS_ATTR_DOMAINS]

@property
@dbus_property
def fallback_dns(self) -> list[tuple[int, DNSAddressFamily, bytes]] | None:
"""Return fallback DNS servers."""
return self.properties[DBUS_ATTR_FALLBACK_DNS]

@property
@dbus_property
def fallback_dns_ex(
self,
) -> list[tuple[int, DNSAddressFamily, bytes, int, str]] | None:
"""Return fallback DNS servers including port and server name."""
return self.properties[DBUS_ATTR_FALLBACK_DNS_EX]

@property
@dbus_property
def llmnr(self) -> MulticastProtocolEnabled | None:
"""Return LLMNR enabled."""
return self.properties[DBUS_ATTR_LLMNR]

@property
@dbus_property
def llmnr_hostname(self) -> str | None:
"""Return LLMNR hostname on network."""
return self.properties[DBUS_ATTR_LLMNR_HOSTNAME]

@property
@dbus_property
def multicast_dns(self) -> MulticastProtocolEnabled | None:
"""Return MDNS enabled."""
return self.properties[DBUS_ATTR_MULTICAST_DNS]

@property
@dbus_property
def resolv_conf_mode(self) -> ResolvConfMode | None:
"""Return how /etc/resolv.conf managed on host."""
return self.properties[DBUS_ATTR_RESOLV_CONF_MODE]

@property
@dbus_property
def transaction_statistics(self) -> tuple[int, int] | None:
"""Return transactions processing and processed since last reset."""
return self.properties[DBUS_ATTR_TRANSACTION_STATISTICS]

@dbus_connected
async def update(self):
"""Update Properties."""
self.properties = await self.dbus.get_properties(DBUS_IFACE_RESOLVED_MANAGER)
1 change: 1 addition & 0 deletions supervisor/resolution/const.py
Expand Up @@ -41,6 +41,7 @@ class UnsupportedReason(str, Enum):
SOFTWARE = "software"
SOURCE_MODS = "source_mods"
SYSTEMD = "systemd"
SYSTEMD_RESOLVED = "systemd_resolved"


class UnhealthyReason(str, Enum):
Expand Down