MVP: Add Network Manager context (#1937)
Co-authored-by: Pascal Vizeli <pvizeli@syshack.ch>
This commit is contained in:
parent
1e953167b6
commit
9bcb15dbc0
59
API.md
59
API.md
|
@ -442,6 +442,65 @@ Proxy to Home Assistant Core websocket.
|
|||
}
|
||||
```
|
||||
|
||||
### Network
|
||||
|
||||
Network operations over the API
|
||||
|
||||
#### GET `/network/info`
|
||||
|
||||
Get network information
|
||||
|
||||
```json
|
||||
{
|
||||
"interfaces": {
|
||||
"enp0s31f6": {
|
||||
"ip_address": "192.168.2.148/24",
|
||||
"gateway": "192.168.2.1",
|
||||
"id": "Wired connection 1",
|
||||
"type": "802-3-ethernet",
|
||||
"nameservers": ["192.168.2.1"],
|
||||
"method": "static",
|
||||
"primary": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### GET `/network/{interface}/info`
|
||||
|
||||
Get information for a single interface
|
||||
|
||||
```json
|
||||
{
|
||||
"ip_address": "192.168.2.148/24",
|
||||
"gateway": "192.168.2.1",
|
||||
"id": "Wired connection 1",
|
||||
"type": "802-3-ethernet",
|
||||
"nameservers": ["192.168.2.1"],
|
||||
"method": "dhcp",
|
||||
"primary": true
|
||||
}
|
||||
```
|
||||
|
||||
#### POST `/network/{interface}/update`
|
||||
|
||||
Update information for a single interface
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description |
|
||||
| --------- | ---------------------------------------------------------------------- |
|
||||
| `address` | The new IP address for the interface in the X.X.X.X/XX format |
|
||||
| `dns` | Comma seperated list of DNS servers to use |
|
||||
| `gateway` | The gateway the interface should use |
|
||||
| `method` | Set if the interface should use DHCP or not, can be `dhcp` or `static` |
|
||||
|
||||
_All options are optional._
|
||||
|
||||
**NB!: If you change the `address` or `gateway` you may need to reconnect to the new address**
|
||||
|
||||
The result will be a updated object.
|
||||
|
||||
### RESTful for API add-ons
|
||||
|
||||
If an add-on will call itself, you can use `/addons/self/...`.
|
||||
|
|
|
@ -7,6 +7,7 @@ pre-commit==2.7.1
|
|||
pydocstyle==5.1.0
|
||||
pylint==2.6.0
|
||||
pytest-aiohttp==0.3.0
|
||||
pytest-asyncio==0.12.0 # NB!: Versions over 0.12.0 breaks pytest-aiohttp (https://github.com/aio-libs/pytest-aiohttp/issues/16)
|
||||
pytest-cov==2.10.1
|
||||
pytest-timeout==1.4.2
|
||||
pytest==6.0.1
|
||||
|
|
|
@ -18,6 +18,7 @@ from .host import APIHost
|
|||
from .info import APIInfo
|
||||
from .ingress import APIIngress
|
||||
from .multicast import APIMulticast
|
||||
from .network import APINetwork
|
||||
from .os import APIOS
|
||||
from .proxy import APIProxy
|
||||
from .security import SecurityMiddleware
|
||||
|
@ -54,6 +55,7 @@ class RestAPI(CoreSysAttributes):
|
|||
self._register_os()
|
||||
self._register_cli()
|
||||
self._register_multicast()
|
||||
self._register_network()
|
||||
self._register_hardware()
|
||||
self._register_homeassistant()
|
||||
self._register_proxy()
|
||||
|
@ -89,6 +91,24 @@ class RestAPI(CoreSysAttributes):
|
|||
]
|
||||
)
|
||||
|
||||
def _register_network(self) -> None:
|
||||
"""Register network functions."""
|
||||
api_network = APINetwork()
|
||||
api_network.coresys = self.coresys
|
||||
|
||||
self.webapp.add_routes(
|
||||
[
|
||||
web.get("/network/info", api_network.info),
|
||||
web.get(
|
||||
"/network/interface/{interface}/info", api_network.interface_info
|
||||
),
|
||||
web.post(
|
||||
"/network/interface/{interface}/update",
|
||||
api_network.interface_update,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
def _register_os(self) -> None:
|
||||
"""Register OS functions."""
|
||||
api_os = APIOS()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Init file for Supervisor host RESTful API."""
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Awaitable
|
||||
|
||||
from aiohttp import web
|
||||
|
@ -26,8 +25,6 @@ from ..const import (
|
|||
from ..coresys import CoreSysAttributes
|
||||
from .utils import api_process, api_process_raw, api_validate
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
SERVICE = "service"
|
||||
|
||||
SCHEMA_OPTIONS = vol.Schema({vol.Optional(ATTR_HOSTNAME): vol.Coerce(str)})
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
"""REST API for network."""
|
||||
import asyncio
|
||||
from typing import Any, Dict
|
||||
|
||||
from aiohttp import web
|
||||
import voluptuous as vol
|
||||
|
||||
from ..const import (
|
||||
ATTR_ADDRESS,
|
||||
ATTR_DNS,
|
||||
ATTR_GATEWAY,
|
||||
ATTR_ID,
|
||||
ATTR_INTERFACE,
|
||||
ATTR_INTERFACES,
|
||||
ATTR_IP_ADDRESS,
|
||||
ATTR_METHOD,
|
||||
ATTR_METHODS,
|
||||
ATTR_NAMESERVERS,
|
||||
ATTR_PRIMARY,
|
||||
ATTR_TYPE,
|
||||
)
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..dbus.const import InterfaceMethodSimple
|
||||
from ..dbus.network.interface import NetworkInterface
|
||||
from ..dbus.network.utils import int2ip
|
||||
from ..exceptions import APIError
|
||||
from .utils import api_process, api_validate
|
||||
|
||||
SCHEMA_UPDATE = vol.Schema(
|
||||
{
|
||||
vol.Optional(ATTR_ADDRESS): vol.Coerce(str),
|
||||
vol.Optional(ATTR_METHOD): vol.In(ATTR_METHODS),
|
||||
vol.Optional(ATTR_GATEWAY): vol.Coerce(str),
|
||||
vol.Optional(ATTR_DNS): [str],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def interface_information(interface: NetworkInterface) -> dict:
|
||||
"""Return a dict with information of a interface to be used in th API."""
|
||||
return {
|
||||
ATTR_IP_ADDRESS: f"{interface.ip_address}/{interface.prefix}",
|
||||
ATTR_GATEWAY: interface.gateway,
|
||||
ATTR_ID: interface.id,
|
||||
ATTR_TYPE: interface.type,
|
||||
ATTR_NAMESERVERS: [int2ip(x) for x in interface.nameservers],
|
||||
ATTR_METHOD: InterfaceMethodSimple.DHCP
|
||||
if interface.method == "auto"
|
||||
else InterfaceMethodSimple.STATIC,
|
||||
ATTR_PRIMARY: interface.primary,
|
||||
}
|
||||
|
||||
|
||||
class APINetwork(CoreSysAttributes):
|
||||
"""Handle REST API for network."""
|
||||
|
||||
@api_process
|
||||
async def info(self, request: web.Request) -> Dict[str, Any]:
|
||||
"""Return network information."""
|
||||
interfaces = {}
|
||||
for interface in self.sys_host.network.interfaces:
|
||||
interfaces[
|
||||
self.sys_host.network.interfaces[interface].name
|
||||
] = interface_information(self.sys_host.network.interfaces[interface])
|
||||
|
||||
return {ATTR_INTERFACES: interfaces}
|
||||
|
||||
@api_process
|
||||
async def interface_info(self, request: web.Request) -> Dict[str, Any]:
|
||||
"""Return network information for a interface."""
|
||||
req_interface = request.match_info.get(ATTR_INTERFACE)
|
||||
for interface in self.sys_host.network.interfaces:
|
||||
if req_interface == self.sys_host.network.interfaces[interface].name:
|
||||
return interface_information(
|
||||
self.sys_host.network.interfaces[interface]
|
||||
)
|
||||
|
||||
return {}
|
||||
|
||||
@api_process
|
||||
async def interface_update(self, request: web.Request) -> Dict[str, Any]:
|
||||
"""Update the configuration of an interface."""
|
||||
req_interface = request.match_info.get(ATTR_INTERFACE)
|
||||
|
||||
if not self.sys_host.network.interfaces.get(req_interface):
|
||||
raise APIError(f"Interface {req_interface} does not exsist")
|
||||
|
||||
args = await api_validate(SCHEMA_UPDATE, request)
|
||||
if not args:
|
||||
raise APIError("You need to supply at least one option to update")
|
||||
|
||||
await asyncio.shield(
|
||||
self.sys_host.network.interfaces[req_interface].update_settings(**args)
|
||||
)
|
||||
|
||||
await asyncio.shield(self.sys_host.network.update())
|
||||
|
||||
return await asyncio.shield(self.interface_info(request))
|
|
@ -6,8 +6,8 @@ from pathlib import Path
|
|||
SUPERVISOR_VERSION = "236"
|
||||
|
||||
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
||||
URL_HASSIO_VERSION = "https://version.home-assistant.io/{channel}.json"
|
||||
URL_HASSIO_APPARMOR = "https://version.home-assistant.io/apparmor.txt"
|
||||
URL_HASSIO_VERSION = "https://version.home-assistant.io/{channel}.json"
|
||||
|
||||
URL_HASSOS_OTA = (
|
||||
"https://github.com/home-assistant/operating-system/releases/download/"
|
||||
|
@ -16,22 +16,22 @@ URL_HASSOS_OTA = (
|
|||
|
||||
SUPERVISOR_DATA = Path("/data")
|
||||
|
||||
FILE_HASSIO_AUTH = Path(SUPERVISOR_DATA, "auth.json")
|
||||
FILE_HASSIO_ADDONS = Path(SUPERVISOR_DATA, "addons.json")
|
||||
FILE_HASSIO_CONFIG = Path(SUPERVISOR_DATA, "config.json")
|
||||
FILE_HASSIO_HOMEASSISTANT = Path(SUPERVISOR_DATA, "homeassistant.json")
|
||||
FILE_HASSIO_UPDATER = Path(SUPERVISOR_DATA, "updater.json")
|
||||
FILE_HASSIO_SERVICES = Path(SUPERVISOR_DATA, "services.json")
|
||||
FILE_HASSIO_DISCOVERY = Path(SUPERVISOR_DATA, "discovery.json")
|
||||
FILE_HASSIO_INGRESS = Path(SUPERVISOR_DATA, "ingress.json")
|
||||
FILE_HASSIO_DNS = Path(SUPERVISOR_DATA, "dns.json")
|
||||
FILE_HASSIO_AUDIO = Path(SUPERVISOR_DATA, "audio.json")
|
||||
FILE_HASSIO_AUTH = Path(SUPERVISOR_DATA, "auth.json")
|
||||
FILE_HASSIO_CLI = Path(SUPERVISOR_DATA, "cli.json")
|
||||
FILE_HASSIO_CONFIG = Path(SUPERVISOR_DATA, "config.json")
|
||||
FILE_HASSIO_DISCOVERY = Path(SUPERVISOR_DATA, "discovery.json")
|
||||
FILE_HASSIO_DNS = Path(SUPERVISOR_DATA, "dns.json")
|
||||
FILE_HASSIO_HOMEASSISTANT = Path(SUPERVISOR_DATA, "homeassistant.json")
|
||||
FILE_HASSIO_INGRESS = Path(SUPERVISOR_DATA, "ingress.json")
|
||||
FILE_HASSIO_MULTICAST = Path(SUPERVISOR_DATA, "multicast.json")
|
||||
FILE_HASSIO_SERVICES = Path(SUPERVISOR_DATA, "services.json")
|
||||
FILE_HASSIO_UPDATER = Path(SUPERVISOR_DATA, "updater.json")
|
||||
|
||||
MACHINE_ID = Path("/etc/machine-id")
|
||||
SOCKET_DOCKER = Path("/run/docker.sock")
|
||||
SOCKET_DBUS = Path("/run/dbus/system_bus_socket")
|
||||
SOCKET_DOCKER = Path("/run/docker.sock")
|
||||
|
||||
DOCKER_NETWORK = "hassio"
|
||||
DOCKER_NETWORK_MASK = ip_network("172.30.32.0/23")
|
||||
|
@ -44,216 +44,233 @@ DOCKER_IMAGE_DENYLIST = [
|
|||
|
||||
DNS_SUFFIX = "local.hass.io"
|
||||
|
||||
LABEL_VERSION = "io.hass.version"
|
||||
LABEL_ARCH = "io.hass.arch"
|
||||
LABEL_TYPE = "io.hass.type"
|
||||
LABEL_MACHINE = "io.hass.machine"
|
||||
LABEL_TYPE = "io.hass.type"
|
||||
LABEL_VERSION = "io.hass.version"
|
||||
|
||||
META_ADDON = "addon"
|
||||
META_SUPERVISOR = "supervisor"
|
||||
META_HOMEASSISTANT = "homeassistant"
|
||||
META_SUPERVISOR = "supervisor"
|
||||
|
||||
JSON_RESULT = "result"
|
||||
JSON_DATA = "data"
|
||||
JSON_MESSAGE = "message"
|
||||
JSON_RESULT = "result"
|
||||
|
||||
RESULT_ERROR = "error"
|
||||
RESULT_OK = "ok"
|
||||
|
||||
CONTENT_TYPE_BINARY = "application/octet-stream"
|
||||
CONTENT_TYPE_PNG = "image/png"
|
||||
CONTENT_TYPE_JSON = "application/json"
|
||||
CONTENT_TYPE_TEXT = "text/plain"
|
||||
CONTENT_TYPE_PNG = "image/png"
|
||||
CONTENT_TYPE_TAR = "application/tar"
|
||||
CONTENT_TYPE_TEXT = "text/plain"
|
||||
CONTENT_TYPE_URL = "application/x-www-form-urlencoded"
|
||||
COOKIE_INGRESS = "ingress_session"
|
||||
|
||||
HEADER_TOKEN = "X-Supervisor-Token"
|
||||
HEADER_TOKEN_OLD = "X-Hassio-Key"
|
||||
|
||||
ENV_TOKEN_OLD = "HASSIO_TOKEN"
|
||||
ENV_TOKEN = "SUPERVISOR_TOKEN"
|
||||
ENV_TIME = "TZ"
|
||||
ENV_TOKEN = "SUPERVISOR_TOKEN"
|
||||
ENV_TOKEN_OLD = "HASSIO_TOKEN"
|
||||
|
||||
ENV_HOMEASSISTANT_REPOSITORY = "HOMEASSISTANT_REPOSITORY"
|
||||
ENV_SUPERVISOR_SHARE = "SUPERVISOR_SHARE"
|
||||
ENV_SUPERVISOR_NAME = "SUPERVISOR_NAME"
|
||||
ENV_SUPERVISOR_MACHINE = "SUPERVISOR_MACHINE"
|
||||
ENV_SUPERVISOR_DEV = "SUPERVISOR_DEV"
|
||||
ENV_SUPERVISOR_MACHINE = "SUPERVISOR_MACHINE"
|
||||
ENV_SUPERVISOR_NAME = "SUPERVISOR_NAME"
|
||||
ENV_SUPERVISOR_SHARE = "SUPERVISOR_SHARE"
|
||||
|
||||
REQUEST_FROM = "HASSIO_FROM"
|
||||
|
||||
ATTR_DOCKER = "docker"
|
||||
ATTR_SUPERVISOR = "supervisor"
|
||||
ATTR_MACHINE = "machine"
|
||||
ATTR_MULTICAST = "multicast"
|
||||
ATTR_WAIT_BOOT = "wait_boot"
|
||||
ATTR_DEPLOYMENT = "deployment"
|
||||
ATTR_WATCHDOG = "watchdog"
|
||||
ATTR_CHANGELOG = "changelog"
|
||||
ATTR_LOGGING = "logging"
|
||||
ATTR_DATE = "date"
|
||||
ATTR_ARCH = "arch"
|
||||
ATTR_LONG_DESCRIPTION = "long_description"
|
||||
ATTR_HOSTNAME = "hostname"
|
||||
ATTR_TIMEZONE = "timezone"
|
||||
ATTR_ARGS = "args"
|
||||
ATTR_OPERATING_SYSTEM = "operating_system"
|
||||
ATTR_CHASSIS = "chassis"
|
||||
ATTR_TYPE = "type"
|
||||
ATTR_SOURCE = "source"
|
||||
ATTR_FEATURES = "features"
|
||||
ATTR_ACCESS_TOKEN = "access_token"
|
||||
ATTR_ACTIVE = "active"
|
||||
ATTR_ADDON = "addon"
|
||||
ATTR_ADDONS = "addons"
|
||||
ATTR_PROVIDERS = "providers"
|
||||
ATTR_VERSION = "version"
|
||||
ATTR_VERSION_LATEST = "version_latest"
|
||||
ATTR_AUTO_UART = "auto_uart"
|
||||
ATTR_USB = "usb"
|
||||
ATTR_LAST_BOOT = "last_boot"
|
||||
ATTR_CHANNEL = "channel"
|
||||
ATTR_NAME = "name"
|
||||
ATTR_SLUG = "slug"
|
||||
ATTR_DESCRIPTON = "description"
|
||||
ATTR_STARTUP = "startup"
|
||||
ATTR_BOOT = "boot"
|
||||
ATTR_PORTS = "ports"
|
||||
ATTR_PORTS_DESCRIPTION = "ports_description"
|
||||
ATTR_PORT = "port"
|
||||
ATTR_SSL = "ssl"
|
||||
ATTR_MAP = "map"
|
||||
ATTR_WEBUI = "webui"
|
||||
ATTR_OPTIONS = "options"
|
||||
ATTR_INSTALLED = "installed"
|
||||
ATTR_DETACHED = "detached"
|
||||
ATTR_STATE = "state"
|
||||
ATTR_SCHEMA = "schema"
|
||||
ATTR_IMAGE = "image"
|
||||
ATTR_ICON = "icon"
|
||||
ATTR_LOGO = "logo"
|
||||
ATTR_STDIN = "stdin"
|
||||
ATTR_ADDONS_CUSTOM_LIST = "addons_custom_list"
|
||||
ATTR_ADDONS_REPOSITORIES = "addons_repositories"
|
||||
ATTR_REPOSITORY = "repository"
|
||||
ATTR_REPOSITORIES = "repositories"
|
||||
ATTR_URL = "url"
|
||||
ATTR_MAINTAINER = "maintainer"
|
||||
ATTR_PASSWORD = "password"
|
||||
ATTR_TOTP = "totp"
|
||||
ATTR_INITIALIZE = "initialize"
|
||||
ATTR_LOCATON = "location"
|
||||
ATTR_BUILD = "build"
|
||||
ATTR_DEVICES = "devices"
|
||||
ATTR_ENVIRONMENT = "environment"
|
||||
ATTR_HOST_NETWORK = "host_network"
|
||||
ATTR_HOST_PID = "host_pid"
|
||||
ATTR_HOST_IPC = "host_ipc"
|
||||
ATTR_HOST_DBUS = "host_dbus"
|
||||
ATTR_NETWORK = "network"
|
||||
ATTR_NETWORK_DESCRIPTION = "network_description"
|
||||
ATTR_TMPFS = "tmpfs"
|
||||
ATTR_PRIVILEGED = "privileged"
|
||||
ATTR_USER = "user"
|
||||
ATTR_SYSTEM = "system"
|
||||
ATTR_SNAPSHOTS = "snapshots"
|
||||
ATTR_HOMEASSISTANT = "homeassistant"
|
||||
ATTR_HASSIO_API = "hassio_api"
|
||||
ATTR_HOMEASSISTANT_API = "homeassistant_api"
|
||||
ATTR_UUID = "uuid"
|
||||
ATTR_FOLDERS = "folders"
|
||||
ATTR_SIZE = "size"
|
||||
ATTR_TYPE = "type"
|
||||
ATTR_TIMEOUT = "timeout"
|
||||
ATTR_AUTO_UPDATE = "auto_update"
|
||||
ATTR_VIDEO = "video"
|
||||
ATTR_ADDRESS = "address"
|
||||
ATTR_ADDRESS_DATA = "address-data"
|
||||
ATTR_ADMIN = "admin"
|
||||
ATTR_ADVANCED = "advanced"
|
||||
ATTR_APPARMOR = "apparmor"
|
||||
ATTR_APPLICATION = "application"
|
||||
ATTR_ARCH = "arch"
|
||||
ATTR_ARGS = "args"
|
||||
ATTR_AUDIO = "audio"
|
||||
ATTR_AUDIO_INPUT = "audio_input"
|
||||
ATTR_AUDIO_OUTPUT = "audio_output"
|
||||
ATTR_INPUT = "input"
|
||||
ATTR_OUTPUT = "output"
|
||||
ATTR_AUTH_API = "auth_api"
|
||||
ATTR_AUTO_UART = "auto_uart"
|
||||
ATTR_AUTO_UPDATE = "auto_update"
|
||||
ATTR_AVAILABLE = "available"
|
||||
ATTR_BLK_READ = "blk_read"
|
||||
ATTR_BLK_WRITE = "blk_write"
|
||||
ATTR_BOARD = "board"
|
||||
ATTR_BOOT = "boot"
|
||||
ATTR_BRANCH = "branch"
|
||||
ATTR_BUILD = "build"
|
||||
ATTR_BUILD_FROM = "build_from"
|
||||
ATTR_CARD = "card"
|
||||
ATTR_CHANGELOG = "changelog"
|
||||
ATTR_CHANNEL = "channel"
|
||||
ATTR_CHASSIS = "chassis"
|
||||
ATTR_CLI = "cli"
|
||||
ATTR_CONFIG = "config"
|
||||
ATTR_CONNECTIONS = "connections"
|
||||
ATTR_CPE = "cpe"
|
||||
ATTR_CPU_PERCENT = "cpu_percent"
|
||||
ATTR_CRYPTO = "crypto"
|
||||
ATTR_DATE = "date"
|
||||
ATTR_DEBUG = "debug"
|
||||
ATTR_DEBUG_BLOCK = "debug_block"
|
||||
ATTR_DEFAULT = "default"
|
||||
ATTR_DEPLOYMENT = "deployment"
|
||||
ATTR_DESCRIPTON = "description"
|
||||
ATTR_DETACHED = "detached"
|
||||
ATTR_DEVICES = "devices"
|
||||
ATTR_DEVICETREE = "devicetree"
|
||||
ATTR_DIAGNOSTICS = "diagnostics"
|
||||
ATTR_DISCOVERY = "discovery"
|
||||
ATTR_DISK = "disk"
|
||||
ATTR_DISK_FREE = "disk_free"
|
||||
ATTR_DISK_TOTAL = "disk_total"
|
||||
ATTR_DISK_USED = "disk_used"
|
||||
ATTR_SERIAL = "serial"
|
||||
ATTR_SECURITY = "security"
|
||||
ATTR_BUILD_FROM = "build_from"
|
||||
ATTR_SQUASH = "squash"
|
||||
ATTR_GPIO = "gpio"
|
||||
ATTR_LEGACY = "legacy"
|
||||
ATTR_ADDONS_CUSTOM_LIST = "addons_custom_list"
|
||||
ATTR_CPU_PERCENT = "cpu_percent"
|
||||
ATTR_NETWORK_RX = "network_rx"
|
||||
ATTR_NETWORK_TX = "network_tx"
|
||||
ATTR_MEMORY_LIMIT = "memory_limit"
|
||||
ATTR_MEMORY_USAGE = "memory_usage"
|
||||
ATTR_MEMORY_PERCENT = "memory_percent"
|
||||
ATTR_BLK_READ = "blk_read"
|
||||
ATTR_BLK_WRITE = "blk_write"
|
||||
ATTR_ADDON = "addon"
|
||||
ATTR_AVAILABLE = "available"
|
||||
ATTR_HOST = "host"
|
||||
ATTR_USERNAME = "username"
|
||||
ATTR_DISCOVERY = "discovery"
|
||||
ATTR_CONFIG = "config"
|
||||
ATTR_SERVICES = "services"
|
||||
ATTR_SERVICE = "service"
|
||||
ATTR_DISCOVERY = "discovery"
|
||||
ATTR_PROTECTED = "protected"
|
||||
ATTR_CRYPTO = "crypto"
|
||||
ATTR_BRANCH = "branch"
|
||||
ATTR_KERNEL = "kernel"
|
||||
ATTR_APPARMOR = "apparmor"
|
||||
ATTR_DEVICETREE = "devicetree"
|
||||
ATTR_CPE = "cpe"
|
||||
ATTR_BOARD = "board"
|
||||
ATTR_HASSOS = "hassos"
|
||||
ATTR_REFRESH_TOKEN = "refresh_token"
|
||||
ATTR_ACCESS_TOKEN = "access_token"
|
||||
ATTR_DNS = "dns"
|
||||
ATTR_DOCKER = "docker"
|
||||
ATTR_DOCKER_API = "docker_api"
|
||||
ATTR_DOCUMENTATION = "documentation"
|
||||
ATTR_DOMAINS = "domains"
|
||||
ATTR_ENABLE = "enable"
|
||||
ATTR_ENVIRONMENT = "environment"
|
||||
ATTR_FEATURES = "features"
|
||||
ATTR_FILENAME = "filename"
|
||||
ATTR_FLAGS = "flags"
|
||||
ATTR_FOLDERS = "folders"
|
||||
ATTR_FULL_ACCESS = "full_access"
|
||||
ATTR_PROTECTED = "protected"
|
||||
ATTR_RATING = "rating"
|
||||
ATTR_GATEWAY = "gateway"
|
||||
ATTR_GPIO = "gpio"
|
||||
ATTR_HASSIO_API = "hassio_api"
|
||||
ATTR_HASSIO_ROLE = "hassio_role"
|
||||
ATTR_SUPERVISOR = "supervisor"
|
||||
ATTR_AUTH_API = "auth_api"
|
||||
ATTR_KERNEL_MODULES = "kernel_modules"
|
||||
ATTR_SUPPORTED_ARCH = "supported_arch"
|
||||
ATTR_HASSOS = "hassos"
|
||||
ATTR_HEALTHY = "healthy"
|
||||
ATTR_HOMEASSISTANT = "homeassistant"
|
||||
ATTR_HOMEASSISTANT_API = "homeassistant_api"
|
||||
ATTR_HOST = "host"
|
||||
ATTR_HOST_DBUS = "host_dbus"
|
||||
ATTR_HOST_IPC = "host_ipc"
|
||||
ATTR_HOST_NETWORK = "host_network"
|
||||
ATTR_HOST_PID = "host_pid"
|
||||
ATTR_HOSTNAME = "hostname"
|
||||
ATTR_ICON = "icon"
|
||||
ATTR_ID = "id"
|
||||
ATTR_IMAGE = "image"
|
||||
ATTR_INDEX = "index"
|
||||
ATTR_INGRESS = "ingress"
|
||||
ATTR_INGRESS_PORT = "ingress_port"
|
||||
ATTR_INGRESS_ENTRY = "ingress_entry"
|
||||
ATTR_INGRESS_PANEL = "ingress_panel"
|
||||
ATTR_INGRESS_PORT = "ingress_port"
|
||||
ATTR_INGRESS_TOKEN = "ingress_token"
|
||||
ATTR_INGRESS_URL = "ingress_url"
|
||||
ATTR_INGRESS_PANEL = "ingress_panel"
|
||||
ATTR_INIT = "init"
|
||||
ATTR_INITIALIZE = "initialize"
|
||||
ATTR_INPUT = "input"
|
||||
ATTR_INSTALLED = "installed"
|
||||
ATTR_INTERFACE = "interface"
|
||||
ATTR_INTERFACES = "interfaces"
|
||||
ATTR_IP_ADDRESS = "ip_address"
|
||||
ATTR_IPV4 = "ipv4"
|
||||
ATTR_KERNEL = "kernel"
|
||||
ATTR_KERNEL_MODULES = "kernel_modules"
|
||||
ATTR_LAST_BOOT = "last_boot"
|
||||
ATTR_LEGACY = "legacy"
|
||||
ATTR_LOCALS = "locals"
|
||||
ATTR_LOCATON = "location"
|
||||
ATTR_LOGGING = "logging"
|
||||
ATTR_LOGO = "logo"
|
||||
ATTR_LONG_DESCRIPTION = "long_description"
|
||||
ATTR_MACHINE = "machine"
|
||||
ATTR_MAINTAINER = "maintainer"
|
||||
ATTR_MAP = "map"
|
||||
ATTR_MEMORY_LIMIT = "memory_limit"
|
||||
ATTR_MEMORY_PERCENT = "memory_percent"
|
||||
ATTR_MEMORY_USAGE = "memory_usage"
|
||||
ATTR_METHOD = "method"
|
||||
ATTR_METHODS = ["dhcp", "static"]
|
||||
ATTR_MODE = "mode"
|
||||
ATTR_MULTICAST = "multicast"
|
||||
ATTR_NAME = "name"
|
||||
ATTR_NAMESERVERS = "nameservers"
|
||||
ATTR_NETWORK = "network"
|
||||
ATTR_NETWORK_DESCRIPTION = "network_description"
|
||||
ATTR_NETWORK_RX = "network_rx"
|
||||
ATTR_NETWORK_TX = "network_tx"
|
||||
ATTR_OPERATING_SYSTEM = "operating_system"
|
||||
ATTR_OPTIONS = "options"
|
||||
ATTR_OUTPUT = "output"
|
||||
ATTR_PANEL_ADMIN = "panel_admin"
|
||||
ATTR_PANEL_ICON = "panel_icon"
|
||||
ATTR_PANEL_TITLE = "panel_title"
|
||||
ATTR_PANEL_ADMIN = "panel_admin"
|
||||
ATTR_TITLE = "title"
|
||||
ATTR_ENABLE = "enable"
|
||||
ATTR_IP_ADDRESS = "ip_address"
|
||||
ATTR_SESSION = "session"
|
||||
ATTR_ADMIN = "admin"
|
||||
ATTR_PANELS = "panels"
|
||||
ATTR_DEBUG = "debug"
|
||||
ATTR_DEBUG_BLOCK = "debug_block"
|
||||
ATTR_DNS = "dns"
|
||||
ATTR_PASSWORD = "password"
|
||||
ATTR_PORT = "port"
|
||||
ATTR_PORTS = "ports"
|
||||
ATTR_PORTS_DESCRIPTION = "ports_description"
|
||||
ATTR_PREFIX = "prefix"
|
||||
ATTR_PRIMARY = "primary"
|
||||
ATTR_PRIORITY = "priority"
|
||||
ATTR_PRIVILEGED = "privileged"
|
||||
ATTR_PROTECTED = "protected"
|
||||
ATTR_PROVIDERS = "providers"
|
||||
ATTR_RATING = "rating"
|
||||
ATTR_REFRESH_TOKEN = "refresh_token"
|
||||
ATTR_REPOSITORIES = "repositories"
|
||||
ATTR_REPOSITORY = "repository"
|
||||
ATTR_SCHEMA = "schema"
|
||||
ATTR_SECURITY = "security"
|
||||
ATTR_SERIAL = "serial"
|
||||
ATTR_SERVERS = "servers"
|
||||
ATTR_LOCALS = "locals"
|
||||
ATTR_UDEV = "udev"
|
||||
ATTR_VALUE = "value"
|
||||
ATTR_SERVICE = "service"
|
||||
ATTR_SERVICES = "services"
|
||||
ATTR_SESSION = "session"
|
||||
ATTR_SIZE = "size"
|
||||
ATTR_SLUG = "slug"
|
||||
ATTR_SNAPSHOT_EXCLUDE = "snapshot_exclude"
|
||||
ATTR_DOCUMENTATION = "documentation"
|
||||
ATTR_ADVANCED = "advanced"
|
||||
ATTR_SNAPSHOTS = "snapshots"
|
||||
ATTR_SOURCE = "source"
|
||||
ATTR_SQUASH = "squash"
|
||||
ATTR_SSL = "ssl"
|
||||
ATTR_STAGE = "stage"
|
||||
ATTR_CLI = "cli"
|
||||
ATTR_DEFAULT = "default"
|
||||
ATTR_VOLUME = "volume"
|
||||
ATTR_CARD = "card"
|
||||
ATTR_INDEX = "index"
|
||||
ATTR_ACTIVE = "active"
|
||||
ATTR_APPLICATION = "application"
|
||||
ATTR_INIT = "init"
|
||||
ATTR_DIAGNOSTICS = "diagnostics"
|
||||
ATTR_HEALTHY = "healthy"
|
||||
ATTR_STARTUP = "startup"
|
||||
ATTR_STATE = "state"
|
||||
ATTR_STATIC = "static"
|
||||
ATTR_STDIN = "stdin"
|
||||
ATTR_SUPERVISOR = "supervisor"
|
||||
ATTR_SUPPORTED = "supported"
|
||||
ATTR_SUPPORTED_ARCH = "supported_arch"
|
||||
ATTR_SYSTEM = "system"
|
||||
ATTR_TIMEOUT = "timeout"
|
||||
ATTR_TIMEZONE = "timezone"
|
||||
ATTR_TITLE = "title"
|
||||
ATTR_TMPFS = "tmpfs"
|
||||
ATTR_TOTP = "totp"
|
||||
ATTR_TYPE = "type"
|
||||
ATTR_UDEV = "udev"
|
||||
ATTR_UNSAVED = "unsaved"
|
||||
ATTR_URL = "url"
|
||||
ATTR_USB = "usb"
|
||||
ATTR_USER = "user"
|
||||
ATTR_USERNAME = "username"
|
||||
ATTR_UUID = "uuid"
|
||||
ATTR_VALUE = "value"
|
||||
ATTR_VERSION = "version"
|
||||
ATTR_VERSION_LATEST = "version_latest"
|
||||
ATTR_VIDEO = "video"
|
||||
ATTR_VOLUME = "volume"
|
||||
ATTR_VPN = "vpn"
|
||||
ATTR_WAIT_BOOT = "wait_boot"
|
||||
ATTR_WATCHDOG = "watchdog"
|
||||
ATTR_WEBUI = "webui"
|
||||
|
||||
PROVIDE_SERVICE = "provide"
|
||||
NEED_SERVICE = "need"
|
||||
|
@ -297,16 +314,16 @@ SECURITY_PROFILE = "profile"
|
|||
SECURITY_DEFAULT = "default"
|
||||
SECURITY_DISABLE = "disable"
|
||||
|
||||
PRIVILEGED_DAC_READ_SEARCH = "DAC_READ_SEARCH"
|
||||
PRIVILEGED_IPC_LOCK = "IPC_LOCK"
|
||||
PRIVILEGED_NET_ADMIN = "NET_ADMIN"
|
||||
PRIVILEGED_SYS_ADMIN = "SYS_ADMIN"
|
||||
PRIVILEGED_SYS_RAWIO = "SYS_RAWIO"
|
||||
PRIVILEGED_IPC_LOCK = "IPC_LOCK"
|
||||
PRIVILEGED_SYS_TIME = "SYS_TIME"
|
||||
PRIVILEGED_SYS_NICE = "SYS_NICE"
|
||||
PRIVILEGED_SYS_MODULE = "SYS_MODULE"
|
||||
PRIVILEGED_SYS_RESOURCE = "SYS_RESOURCE"
|
||||
PRIVILEGED_SYS_NICE = "SYS_NICE"
|
||||
PRIVILEGED_SYS_PTRACE = "SYS_PTRACE"
|
||||
PRIVILEGED_DAC_READ_SEARCH = "DAC_READ_SEARCH"
|
||||
PRIVILEGED_SYS_RAWIO = "SYS_RAWIO"
|
||||
PRIVILEGED_SYS_RESOURCE = "SYS_RESOURCE"
|
||||
PRIVILEGED_SYS_TIME = "SYS_TIME"
|
||||
|
||||
PRIVILEGED_ALL = [
|
||||
PRIVILEGED_NET_ADMIN,
|
||||
|
|
|
@ -134,9 +134,9 @@ class Core(CoreSysAttributes):
|
|||
if not self.sys_dbus.hostname.is_connected:
|
||||
self.supported = False
|
||||
_LOGGER.error("Hostname DBUS is not connected")
|
||||
if not self.sys_dbus.nmi_dns.is_connected:
|
||||
if not self.sys_dbus.network.is_connected:
|
||||
self.supported = False
|
||||
_LOGGER.error("NetworkManager DNS DBUS is not connected")
|
||||
_LOGGER.error("NetworkManager is not connected")
|
||||
if not self.sys_dbus.systemd.is_connected:
|
||||
self.supported = False
|
||||
_LOGGER.error("Systemd DBUS is not connected")
|
||||
|
|
|
@ -4,7 +4,7 @@ import logging
|
|||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import DBusNotConnectedError
|
||||
from .hostname import Hostname
|
||||
from .nmi_dns import NMIDnsManager
|
||||
from .network import NetworkManager
|
||||
from .rauc import Rauc
|
||||
from .systemd import Systemd
|
||||
|
||||
|
@ -21,7 +21,7 @@ class DBusManager(CoreSysAttributes):
|
|||
self._systemd: Systemd = Systemd()
|
||||
self._hostname: Hostname = Hostname()
|
||||
self._rauc: Rauc = Rauc()
|
||||
self._nmi_dns: NMIDnsManager = NMIDnsManager()
|
||||
self._network: NetworkManager = NetworkManager()
|
||||
|
||||
@property
|
||||
def systemd(self) -> Systemd:
|
||||
|
@ -39,9 +39,9 @@ class DBusManager(CoreSysAttributes):
|
|||
return self._rauc
|
||||
|
||||
@property
|
||||
def nmi_dns(self) -> NMIDnsManager:
|
||||
"""Return NetworkManager DNS interface."""
|
||||
return self._nmi_dns
|
||||
def network(self) -> NetworkManager:
|
||||
"""Return NetworkManager interface."""
|
||||
return self._network
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Connect interfaces to D-Bus."""
|
||||
|
@ -50,7 +50,7 @@ class DBusManager(CoreSysAttributes):
|
|||
await self.systemd.connect()
|
||||
await self.hostname.connect()
|
||||
await self.rauc.connect()
|
||||
await self.nmi_dns.connect()
|
||||
await self.network.connect()
|
||||
except DBusNotConnectedError:
|
||||
_LOGGER.error(
|
||||
"No DBus support from Host. Disabled any kind of host control!"
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
"""Constants for DBUS."""
|
||||
from enum import Enum
|
||||
|
||||
DBUS_NAME_CONNECTION_ACTIVE = "org.freedesktop.NetworkManager.Connection.Active"
|
||||
DBUS_NAME_DEVICE = "org.freedesktop.NetworkManager.Device"
|
||||
DBUS_NAME_DNS = "org.freedesktop.NetworkManager.DnsManager"
|
||||
DBUS_NAME_HOSTNAME = "org.freedesktop.hostname1"
|
||||
DBUS_NAME_IP4CONFIG = "org.freedesktop.NetworkManager.IP4Config"
|
||||
DBUS_NAME_NM = "org.freedesktop.NetworkManager"
|
||||
DBUS_NAME_RAUC = "de.pengutronix.rauc"
|
||||
DBUS_NAME_RAUC_INSTALLER = "de.pengutronix.rauc.Installer"
|
||||
DBUS_NAME_RAUC_INSTALLER_COMPLETED = "de.pengutronix.rauc.Installer.Completed"
|
||||
DBUS_NAME_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection"
|
||||
DBUS_NAME_SYSTEMD = "org.freedesktop.systemd1"
|
||||
|
||||
DBUS_OBJECT_BASE = "/"
|
||||
DBUS_OBJECT_DNS = "/org/freedesktop/NetworkManager/DnsManager"
|
||||
DBUS_OBJECT_HOSTNAME = "/org/freedesktop/hostname1"
|
||||
DBUS_OBJECT_NM = "/org/freedesktop/NetworkManager"
|
||||
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
|
||||
|
||||
DBUS_ATTR_ACTIVE_CONNECTIONS = "ActiveConnections"
|
||||
DBUS_ATTR_ADDRESS_DATA = "AddressData"
|
||||
DBUS_ATTR_BOOT_SLOT = "BootSlot"
|
||||
DBUS_ATTR_CHASSIS = "Chassis"
|
||||
DBUS_ATTR_COMPATIBLE = "Compatible"
|
||||
DBUS_ATTR_CONFIGURATION = "Configuration"
|
||||
DBUS_ATTR_CONNECTION = "Connection"
|
||||
DBUS_ATTR_DEFAULT = "Default"
|
||||
DBUS_ATTR_DEPLOYMENT = "Deployment"
|
||||
DBUS_ATTR_DEVICE_INTERFACE = "Interface"
|
||||
DBUS_ATTR_DEVICE_TYPE = "DeviceType"
|
||||
DBUS_ATTR_DEVICES = "Devices"
|
||||
DBUS_ATTR_GATEWAY = "Gateway"
|
||||
DBUS_ATTR_ID = "Id"
|
||||
DBUS_ATTR_IP4ADDRESS = "Ip4Address"
|
||||
DBUS_ATTR_IP4CONFIG = "Ip4Config"
|
||||
DBUS_ATTR_KERNEL_RELEASE = "KernelRelease"
|
||||
DBUS_ATTR_LAST_ERROR = "LastError"
|
||||
DBUS_ATTR_MODE = "Mode"
|
||||
DBUS_ATTR_NAMESERVERS = "Nameservers"
|
||||
DBUS_ATTR_OPERATING_SYSTEM_PRETTY_NAME = "OperatingSystemPrettyName"
|
||||
DBUS_ATTR_OPERATION = "Operation"
|
||||
DBUS_ATTR_PRIMARY_CONNECTION = "PrimaryConnection"
|
||||
DBUS_ATTR_RCMANAGER = "RcManager"
|
||||
DBUS_ATTR_REAL = "Real"
|
||||
DBUS_ATTR_STATE = "State"
|
||||
DBUS_ATTR_STATIC_HOSTNAME = "StaticHostname"
|
||||
DBUS_ATTR_STATIC_OPERATING_SYSTEM_CPE_NAME = "OperatingSystemCPEName"
|
||||
DBUS_ATTR_TYPE = "Type"
|
||||
DBUS_ATTR_UUID = "Uuid"
|
||||
DBUS_ATTR_VARIANT = "Variant"
|
||||
|
||||
|
||||
class RaucState(str, Enum):
|
||||
"""Rauc slot states."""
|
||||
|
||||
GOOD = "good"
|
||||
BAD = "bad"
|
||||
ACTIVE = "active"
|
||||
|
||||
|
||||
class InterfaceMethod(str, Enum):
|
||||
"""Interface method simple."""
|
||||
|
||||
AUTO = "auto"
|
||||
MANUAL = "manual"
|
||||
|
||||
|
||||
class InterfaceMethodSimple(str, Enum):
|
||||
"""Interface method."""
|
||||
|
||||
DHCP = "dhcp"
|
||||
STATIC = "static"
|
|
@ -4,14 +4,21 @@ from typing import Optional
|
|||
|
||||
from ..exceptions import DBusError, DBusInterfaceError
|
||||
from ..utils.gdbus import DBus
|
||||
from .const import (
|
||||
DBUS_ATTR_CHASSIS,
|
||||
DBUS_ATTR_DEPLOYMENT,
|
||||
DBUS_ATTR_KERNEL_RELEASE,
|
||||
DBUS_ATTR_OPERATING_SYSTEM_PRETTY_NAME,
|
||||
DBUS_ATTR_STATIC_HOSTNAME,
|
||||
DBUS_ATTR_STATIC_OPERATING_SYSTEM_CPE_NAME,
|
||||
DBUS_NAME_HOSTNAME,
|
||||
DBUS_OBJECT_HOSTNAME,
|
||||
)
|
||||
from .interface import DBusInterface
|
||||
from .utils import dbus_connected
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
DBUS_NAME = "org.freedesktop.hostname1"
|
||||
DBUS_OBJECT = "/org/freedesktop/hostname1"
|
||||
|
||||
|
||||
class Hostname(DBusInterface):
|
||||
"""Handle D-Bus interface for hostname/system."""
|
||||
|
@ -28,7 +35,7 @@ class Hostname(DBusInterface):
|
|||
async def connect(self):
|
||||
"""Connect to system's D-Bus."""
|
||||
try:
|
||||
self.dbus = await DBus.connect(DBUS_NAME, DBUS_OBJECT)
|
||||
self.dbus = await DBus.connect(DBUS_NAME_HOSTNAME, DBUS_OBJECT_HOSTNAME)
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't connect to hostname")
|
||||
except DBusInterfaceError:
|
||||
|
@ -77,14 +84,14 @@ class Hostname(DBusInterface):
|
|||
@dbus_connected
|
||||
async def update(self):
|
||||
"""Update Properties."""
|
||||
data = await self.dbus.get_properties(DBUS_NAME)
|
||||
data = await self.dbus.get_properties(DBUS_NAME_HOSTNAME)
|
||||
if not data:
|
||||
_LOGGER.warning("Can't get properties for Hostname")
|
||||
return
|
||||
|
||||
self._hostname = data.get("StaticHostname")
|
||||
self._chassis = data.get("Chassis")
|
||||
self._deployment = data.get("Deployment")
|
||||
self._kernel = data.get("KernelRelease")
|
||||
self._operating_system = data.get("OperatingSystemPrettyName")
|
||||
self._cpe = data.get("OperatingSystemCPEName")
|
||||
self._hostname = data.get(DBUS_ATTR_STATIC_HOSTNAME)
|
||||
self._chassis = data.get(DBUS_ATTR_CHASSIS)
|
||||
self._deployment = data.get(DBUS_ATTR_DEPLOYMENT)
|
||||
self._kernel = data.get(DBUS_ATTR_KERNEL_RELEASE)
|
||||
self._operating_system = data.get(DBUS_ATTR_OPERATING_SYSTEM_PRETTY_NAME)
|
||||
self._cpe = data.get(DBUS_ATTR_STATIC_OPERATING_SYSTEM_CPE_NAME)
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
"""Network Manager implementation for DBUS."""
|
||||
import logging
|
||||
from typing import Dict, Optional
|
||||
|
||||
from ...exceptions import DBusError, DBusInterfaceError
|
||||
from ...utils.gdbus import DBus
|
||||
from ..const import (
|
||||
DBUS_ATTR_ACTIVE_CONNECTIONS,
|
||||
DBUS_ATTR_PRIMARY_CONNECTION,
|
||||
DBUS_NAME_NM,
|
||||
DBUS_OBJECT_NM,
|
||||
)
|
||||
from ..interface import DBusInterface
|
||||
from ..utils import dbus_connected
|
||||
from .dns import NetworkManagerDNS
|
||||
from .interface import NetworkInterface
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkManager(DBusInterface):
|
||||
"""Handle D-Bus interface for Network Manager."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize Properties."""
|
||||
self._dns: NetworkManagerDNS = NetworkManagerDNS()
|
||||
self._interfaces: Optional[Dict[str, NetworkInterface]] = []
|
||||
|
||||
@property
|
||||
def dns(self) -> NetworkManagerDNS:
|
||||
"""Return NetworkManager DNS interface."""
|
||||
return self._dns
|
||||
|
||||
@property
|
||||
def interfaces(self) -> Dict[str, NetworkInterface]:
|
||||
"""Return a dictionary of active interfaces."""
|
||||
return self._interfaces
|
||||
|
||||
async def connect(self) -> None:
|
||||
"""Connect to system's D-Bus."""
|
||||
try:
|
||||
self.dbus = await DBus.connect(DBUS_NAME_NM, DBUS_OBJECT_NM)
|
||||
await self.dns.connect()
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't connect to Network Manager")
|
||||
except DBusInterfaceError:
|
||||
_LOGGER.warning(
|
||||
"No Network Manager support on the host. Local network functions have been disabled."
|
||||
)
|
||||
|
||||
@dbus_connected
|
||||
async def update(self):
|
||||
"""Update Properties."""
|
||||
await self.dns.update()
|
||||
|
||||
data = await self.dbus.get_properties(DBUS_NAME_NM)
|
||||
|
||||
if not data:
|
||||
_LOGGER.warning("Can't get properties for Network Manager")
|
||||
return
|
||||
|
||||
self._interfaces = {}
|
||||
for connection in data.get(DBUS_ATTR_ACTIVE_CONNECTIONS, []):
|
||||
interface = NetworkInterface()
|
||||
|
||||
await interface.connect(self.dbus, connection)
|
||||
|
||||
if not interface.connection.default:
|
||||
continue
|
||||
try:
|
||||
await interface.connection.update_information()
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
if interface.connection.object_path == data.get(
|
||||
DBUS_ATTR_PRIMARY_CONNECTION
|
||||
):
|
||||
interface.connection.primary = True
|
||||
|
||||
self._interfaces[interface.name] = interface
|
|
@ -0,0 +1,62 @@
|
|||
"""NetworkConnection object4s for Network Manager."""
|
||||
from typing import List
|
||||
|
||||
import attr
|
||||
|
||||
from ...utils.gdbus import DBus
|
||||
|
||||
|
||||
class NetworkAttributes:
|
||||
"""NetworkAttributes object for Network Manager."""
|
||||
|
||||
def __init__(self, object_path: str, properties: dict) -> None:
|
||||
"""Initialize NetworkAttributes object."""
|
||||
self._properties = properties
|
||||
self.object_path = object_path
|
||||
|
||||
|
||||
@attr.s
|
||||
class AddressData:
|
||||
"""AddressData object for Network Manager."""
|
||||
|
||||
address: str = attr.ib()
|
||||
prefix: int = attr.ib()
|
||||
|
||||
|
||||
@attr.s
|
||||
class IpConfiguration:
|
||||
"""NetworkSettingsIPConfig object for Network Manager."""
|
||||
|
||||
gateway: str = attr.ib()
|
||||
method: str = attr.ib()
|
||||
nameservers: List[int] = attr.ib()
|
||||
address_data: AddressData = attr.ib()
|
||||
|
||||
|
||||
@attr.s
|
||||
class DNSConfiguration:
|
||||
"""DNS configuration Object."""
|
||||
|
||||
nameservers: List[str] = attr.ib()
|
||||
domains: List[str] = attr.ib()
|
||||
interface: str = attr.ib()
|
||||
priority: int = attr.ib()
|
||||
vpn: bool = attr.ib()
|
||||
|
||||
|
||||
@attr.s
|
||||
class NetworkSettings:
|
||||
"""NetworkSettings object for Network Manager."""
|
||||
|
||||
dbus: DBus = attr.ib()
|
||||
|
||||
|
||||
@attr.s
|
||||
class NetworkDevice:
|
||||
"""Device properties."""
|
||||
|
||||
dbus: DBus = attr.ib()
|
||||
interface: str = attr.ib()
|
||||
ip4_address: int = attr.ib()
|
||||
device_type: int = attr.ib()
|
||||
real: bool = attr.ib()
|
|
@ -0,0 +1,124 @@
|
|||
"""Connection object for Network Manager."""
|
||||
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_ADDRESS_DATA,
|
||||
DBUS_ATTR_CONNECTION,
|
||||
DBUS_ATTR_DEFAULT,
|
||||
DBUS_ATTR_DEVICE_INTERFACE,
|
||||
DBUS_ATTR_DEVICE_TYPE,
|
||||
DBUS_ATTR_DEVICES,
|
||||
DBUS_ATTR_GATEWAY,
|
||||
DBUS_ATTR_ID,
|
||||
DBUS_ATTR_IP4ADDRESS,
|
||||
DBUS_ATTR_IP4CONFIG,
|
||||
DBUS_ATTR_NAMESERVERS,
|
||||
DBUS_ATTR_REAL,
|
||||
DBUS_ATTR_STATE,
|
||||
DBUS_ATTR_TYPE,
|
||||
DBUS_ATTR_UUID,
|
||||
DBUS_NAME_DEVICE,
|
||||
DBUS_NAME_IP4CONFIG,
|
||||
DBUS_NAME_NM,
|
||||
)
|
||||
from .configuration import (
|
||||
AddressData,
|
||||
IpConfiguration,
|
||||
NetworkAttributes,
|
||||
NetworkDevice,
|
||||
NetworkSettings,
|
||||
)
|
||||
|
||||
|
||||
class NetworkConnection(NetworkAttributes):
|
||||
"""NetworkConnection object for Network Manager."""
|
||||
|
||||
def __init__(self, object_path: str, properties: dict) -> None:
|
||||
"""Initialize NetworkConnection object."""
|
||||
super().__init__(object_path, properties)
|
||||
self._device_dbus: DBus = None
|
||||
self._settings_dbus: DBus = None
|
||||
self._settings: Optional[NetworkSettings] = None
|
||||
self._ip4_config: Optional[IpConfiguration] = None
|
||||
self._device: Optional[NetworkDevice]
|
||||
self.primary: bool = False
|
||||
|
||||
@property
|
||||
def settings(self) -> NetworkSettings:
|
||||
"""Return a settings object for the connection."""
|
||||
return self._settings
|
||||
|
||||
@property
|
||||
def device(self) -> NetworkDevice:
|
||||
"""Return the device used in the connection."""
|
||||
return self._device
|
||||
|
||||
@property
|
||||
def default(self) -> bool:
|
||||
"""Return a boolean connection is marked as default."""
|
||||
return self._properties[DBUS_ATTR_DEFAULT]
|
||||
|
||||
@property
|
||||
def id(self) -> str:
|
||||
"""Return the id of the connection."""
|
||||
return self._properties[DBUS_ATTR_ID]
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
"""Return the type of the connection."""
|
||||
return self._properties[DBUS_ATTR_TYPE]
|
||||
|
||||
@property
|
||||
def ip4_config(self) -> IpConfiguration:
|
||||
"""Return a ip configuration object for the connection."""
|
||||
return self._ip4_config
|
||||
|
||||
@property
|
||||
def uuid(self) -> str:
|
||||
"""Return the uuid of the connection."""
|
||||
return self._properties[DBUS_ATTR_UUID]
|
||||
|
||||
@property
|
||||
def state(self) -> int:
|
||||
"""
|
||||
Return the state of the connection.
|
||||
|
||||
https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMActiveConnectionState
|
||||
"""
|
||||
return self._properties[DBUS_ATTR_STATE]
|
||||
|
||||
async def update_information(self):
|
||||
"""Update the information for childs ."""
|
||||
settings = await DBus.connect(
|
||||
DBUS_NAME_NM, self._properties[DBUS_ATTR_CONNECTION]
|
||||
)
|
||||
device = await DBus.connect(
|
||||
DBUS_NAME_NM, self._properties[DBUS_ATTR_DEVICES][0]
|
||||
)
|
||||
ip4 = await DBus.connect(DBUS_NAME_NM, self._properties[DBUS_ATTR_IP4CONFIG])
|
||||
|
||||
data = (await settings.Settings.Connection.GetSettings())[0]
|
||||
device_data = await device.get_properties(DBUS_NAME_DEVICE)
|
||||
ip4_data = await ip4.get_properties(DBUS_NAME_IP4CONFIG)
|
||||
|
||||
self._settings = NetworkSettings(settings)
|
||||
|
||||
self._ip4_config = IpConfiguration(
|
||||
ip4_data.get(DBUS_ATTR_GATEWAY),
|
||||
data[ATTR_IPV4].get(ATTR_METHOD),
|
||||
ip4_data.get(DBUS_ATTR_NAMESERVERS),
|
||||
AddressData(
|
||||
ip4_data.get(DBUS_ATTR_ADDRESS_DATA)[0].get(ATTR_ADDRESS),
|
||||
ip4_data.get(DBUS_ATTR_ADDRESS_DATA)[0].get(ATTR_PREFIX),
|
||||
),
|
||||
)
|
||||
|
||||
self._device = NetworkDevice(
|
||||
device,
|
||||
device_data.get(DBUS_ATTR_DEVICE_INTERFACE),
|
||||
device_data.get(DBUS_ATTR_IP4ADDRESS),
|
||||
device_data.get(DBUS_ATTR_DEVICE_TYPE),
|
||||
device_data.get(DBUS_ATTR_REAL),
|
||||
)
|
|
@ -2,31 +2,31 @@
|
|||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
import attr
|
||||
|
||||
from ..exceptions import DBusError, DBusInterfaceError
|
||||
from ..utils.gdbus import DBus
|
||||
from .interface import DBusInterface
|
||||
from .utils import dbus_connected
|
||||
from ...const import (
|
||||
ATTR_DOMAINS,
|
||||
ATTR_INTERFACE,
|
||||
ATTR_NAMESERVERS,
|
||||
ATTR_PRIORITY,
|
||||
ATTR_VPN,
|
||||
)
|
||||
from ...exceptions import DBusError, DBusInterfaceError
|
||||
from ...utils.gdbus import DBus
|
||||
from ..const import (
|
||||
DBUS_ATTR_CONFIGURATION,
|
||||
DBUS_ATTR_MODE,
|
||||
DBUS_ATTR_RCMANAGER,
|
||||
DBUS_NAME_DNS,
|
||||
DBUS_NAME_NM,
|
||||
DBUS_OBJECT_DNS,
|
||||
)
|
||||
from ..interface import DBusInterface
|
||||
from ..utils import dbus_connected
|
||||
from .configuration import DNSConfiguration
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
DBUS_NAME = "org.freedesktop.NetworkManager"
|
||||
DBUS_OBJECT = "/org/freedesktop/NetworkManager/DnsManager"
|
||||
|
||||
|
||||
@attr.s
|
||||
class DNSConfiguration:
|
||||
"""NMI DnsManager configuration Object."""
|
||||
|
||||
nameservers: List[str] = attr.ib()
|
||||
domains: List[str] = attr.ib()
|
||||
interface: str = attr.ib()
|
||||
priority: int = attr.ib()
|
||||
vpn: bool = attr.ib()
|
||||
|
||||
|
||||
class NMIDnsManager(DBusInterface):
|
||||
class NetworkManagerDNS(DBusInterface):
|
||||
"""Handle D-Bus interface for NMI DnsManager."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
@ -53,7 +53,7 @@ class NMIDnsManager(DBusInterface):
|
|||
async def connect(self) -> None:
|
||||
"""Connect to system's D-Bus."""
|
||||
try:
|
||||
self.dbus = await DBus.connect(DBUS_NAME, DBUS_OBJECT)
|
||||
self.dbus = await DBus.connect(DBUS_NAME_NM, DBUS_OBJECT_DNS)
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't connect to DnsManager")
|
||||
except DBusInterfaceError:
|
||||
|
@ -64,22 +64,22 @@ class NMIDnsManager(DBusInterface):
|
|||
@dbus_connected
|
||||
async def update(self):
|
||||
"""Update Properties."""
|
||||
data = await self.dbus.get_properties(f"{DBUS_NAME}.DnsManager")
|
||||
data = await self.dbus.get_properties(DBUS_NAME_DNS)
|
||||
if not data:
|
||||
_LOGGER.warning("Can't get properties for NMI DnsManager")
|
||||
_LOGGER.warning("Can't get properties for DnsManager")
|
||||
return
|
||||
|
||||
self._mode = data.get("Mode")
|
||||
self._rc_manager = data.get("RcManager")
|
||||
self._mode = data.get(DBUS_ATTR_MODE)
|
||||
self._rc_manager = data.get(DBUS_ATTR_RCMANAGER)
|
||||
|
||||
# Parse configuraton
|
||||
self._configuration.clear()
|
||||
for config in data.get("Configuration", []):
|
||||
dns = DNSConfiguration(
|
||||
config.get("nameservers"),
|
||||
config.get("domains"),
|
||||
config.get("interface"),
|
||||
config.get("priority"),
|
||||
config.get("vpn"),
|
||||
self._configuration = [
|
||||
DNSConfiguration(
|
||||
config.get(ATTR_NAMESERVERS),
|
||||
config.get(ATTR_DOMAINS),
|
||||
config.get(ATTR_INTERFACE),
|
||||
config.get(ATTR_PRIORITY),
|
||||
config.get(ATTR_VPN),
|
||||
)
|
||||
self._configuration.append(dns)
|
||||
for config in data.get(DBUS_ATTR_CONFIGURATION, [])
|
||||
]
|
|
@ -0,0 +1,129 @@
|
|||
"""NetworkInterface object for Network Manager."""
|
||||
from ...const import ATTR_ADDRESS, ATTR_DNS, ATTR_GATEWAY, ATTR_METHOD, ATTR_PREFIX
|
||||
from ...utils.gdbus import DBus
|
||||
from ..const import (
|
||||
DBUS_NAME_CONNECTION_ACTIVE,
|
||||
DBUS_NAME_NM,
|
||||
DBUS_OBJECT_BASE,
|
||||
InterfaceMethod,
|
||||
)
|
||||
from .connection import NetworkConnection
|
||||
from .utils import ip2int
|
||||
|
||||
|
||||
class NetworkInterface:
|
||||
"""NetworkInterface object for Network Manager, this serves as a proxy to other objects."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize NetworkConnection object."""
|
||||
self._connection = None
|
||||
self._nm_dbus = None
|
||||
|
||||
@property
|
||||
def nm_dbus(self) -> DBus:
|
||||
"""Return the NM DBus connection."""
|
||||
return self._nm_dbus
|
||||
|
||||
@property
|
||||
def connection(self) -> NetworkConnection:
|
||||
"""Return the connection used for this interface."""
|
||||
return self._connection
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the interface name."""
|
||||
return self.connection.device.interface
|
||||
|
||||
@property
|
||||
def primary(self) -> bool:
|
||||
"""Return true if it's the primary interfac."""
|
||||
return self.connection.primary
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str:
|
||||
"""Return the ip_address."""
|
||||
return self.connection.ip4_config.address_data.address
|
||||
|
||||
@property
|
||||
def prefix(self) -> str:
|
||||
"""Return the network prefix."""
|
||||
return self.connection.ip4_config.address_data.prefix
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
"""Return the interface type."""
|
||||
return self.connection.type
|
||||
|
||||
@property
|
||||
def id(self) -> str:
|
||||
"""Return the interface id."""
|
||||
return self.connection.id
|
||||
|
||||
@property
|
||||
def method(self) -> InterfaceMethod:
|
||||
"""Return the interface method."""
|
||||
return InterfaceMethod(self.connection.ip4_config.method)
|
||||
|
||||
@property
|
||||
def gateway(self) -> str:
|
||||
"""Return the gateway."""
|
||||
return self.connection.ip4_config.gateway
|
||||
|
||||
@property
|
||||
def nameservers(self) -> str:
|
||||
"""Return the nameservers."""
|
||||
return self.connection.ip4_config.nameservers
|
||||
|
||||
async def connect(self, nm_dbus: DBus, connection_object: str) -> None:
|
||||
"""Get connection information."""
|
||||
self._nm_dbus = nm_dbus
|
||||
connection_bus = await DBus.connect(DBUS_NAME_NM, connection_object)
|
||||
connection_properties = await connection_bus.get_properties(
|
||||
DBUS_NAME_CONNECTION_ACTIVE
|
||||
)
|
||||
self._connection = NetworkConnection(connection_object, connection_properties)
|
||||
|
||||
async def update_settings(self, **kwargs) -> None:
|
||||
"""Update IP configuration used for this interface."""
|
||||
if kwargs.get(ATTR_DNS):
|
||||
kwargs[ATTR_DNS] = [ip2int(x.strip()) for x in kwargs[ATTR_DNS]]
|
||||
|
||||
if kwargs.get(ATTR_METHOD):
|
||||
kwargs[ATTR_METHOD] = (
|
||||
InterfaceMethod.MANUAL
|
||||
if kwargs[ATTR_METHOD] == "static"
|
||||
else InterfaceMethod.AUTO
|
||||
)
|
||||
|
||||
if kwargs.get(ATTR_ADDRESS):
|
||||
if "/" in kwargs[ATTR_ADDRESS]:
|
||||
kwargs[ATTR_PREFIX] = kwargs[ATTR_ADDRESS].split("/")[-1]
|
||||
kwargs[ATTR_ADDRESS] = kwargs[ATTR_ADDRESS].split("/")[0]
|
||||
kwargs[ATTR_METHOD] = InterfaceMethod.MANUAL
|
||||
|
||||
await self.connection.settings.dbus.Settings.Connection.Update(
|
||||
f"""{{
|
||||
'connection':
|
||||
{{
|
||||
'id': <'{self.id}'>,
|
||||
'type': <'{self.type}'>
|
||||
}},
|
||||
'ipv4':
|
||||
{{
|
||||
'method': <'{kwargs.get(ATTR_METHOD, self.method)}'>,
|
||||
'dns': <[{",".join([f"uint32 {x}" for x in kwargs.get(ATTR_DNS, self.nameservers)])}]>,
|
||||
'address-data': <[
|
||||
{{
|
||||
'address': <'{kwargs.get(ATTR_ADDRESS, self.ip_address)}'>,
|
||||
'prefix': <uint32 {kwargs.get(ATTR_PREFIX, self.prefix)}>
|
||||
}}]>,
|
||||
'gateway': <'{kwargs.get(ATTR_GATEWAY, self.gateway)}'>
|
||||
}}
|
||||
}}"""
|
||||
)
|
||||
|
||||
await self.nm_dbus.ActivateConnection(
|
||||
self.connection.settings.dbus.object_path,
|
||||
self.connection.device.dbus.object_path,
|
||||
DBUS_OBJECT_BASE,
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
"""Network utils."""
|
||||
from ipaddress import ip_address
|
||||
|
||||
# Return a 32bit representation of a IP Address
|
||||
|
||||
|
||||
def ip2int(address: str) -> int:
|
||||
"""Return a 32bit representation for a IP address."""
|
||||
return int(ip_address(".".join(address.split(".")[::-1])))
|
||||
|
||||
|
||||
def int2ip(bitaddress: int) -> int:
|
||||
"""Return a IP Address object from a 32bit representation."""
|
||||
return ".".join([str(bitaddress >> (i << 3) & 0xFF) for i in range(0, 4)])
|
|
@ -1,26 +1,26 @@
|
|||
"""D-Bus interface for rauc."""
|
||||
from enum import Enum
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from ..exceptions import DBusError, DBusInterfaceError
|
||||
from ..utils.gdbus import DBus
|
||||
from .const import (
|
||||
DBUS_ATTR_BOOT_SLOT,
|
||||
DBUS_ATTR_COMPATIBLE,
|
||||
DBUS_ATTR_LAST_ERROR,
|
||||
DBUS_ATTR_OPERATION,
|
||||
DBUS_ATTR_VARIANT,
|
||||
DBUS_NAME_RAUC,
|
||||
DBUS_NAME_RAUC_INSTALLER,
|
||||
DBUS_NAME_RAUC_INSTALLER_COMPLETED,
|
||||
DBUS_OBJECT_BASE,
|
||||
RaucState,
|
||||
)
|
||||
from .interface import DBusInterface
|
||||
from .utils import dbus_connected
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
DBUS_NAME = "de.pengutronix.rauc"
|
||||
DBUS_OBJECT = "/"
|
||||
|
||||
|
||||
class RaucState(str, Enum):
|
||||
"""Rauc slot states."""
|
||||
|
||||
GOOD = "good"
|
||||
BAD = "bad"
|
||||
ACTIVE = "active"
|
||||
|
||||
|
||||
class Rauc(DBusInterface):
|
||||
"""Handle D-Bus interface for rauc."""
|
||||
|
@ -36,7 +36,7 @@ class Rauc(DBusInterface):
|
|||
async def connect(self):
|
||||
"""Connect to D-Bus."""
|
||||
try:
|
||||
self.dbus = await DBus.connect(DBUS_NAME, DBUS_OBJECT)
|
||||
self.dbus = await DBus.connect(DBUS_NAME_RAUC, DBUS_OBJECT_BASE)
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't connect to rauc")
|
||||
except DBusInterfaceError:
|
||||
|
@ -89,7 +89,7 @@ class Rauc(DBusInterface):
|
|||
|
||||
Return a coroutine.
|
||||
"""
|
||||
return self.dbus.wait_signal(f"{DBUS_NAME}.Installer.Completed")
|
||||
return self.dbus.wait_signal(DBUS_NAME_RAUC_INSTALLER_COMPLETED)
|
||||
|
||||
@dbus_connected
|
||||
def mark(self, state: RaucState, slot_identifier: str):
|
||||
|
@ -102,13 +102,13 @@ class Rauc(DBusInterface):
|
|||
@dbus_connected
|
||||
async def update(self):
|
||||
"""Update Properties."""
|
||||
data = await self.dbus.get_properties(f"{DBUS_NAME}.Installer")
|
||||
data = await self.dbus.get_properties(DBUS_NAME_RAUC_INSTALLER)
|
||||
if not data:
|
||||
_LOGGER.warning("Can't get properties for rauc")
|
||||
return
|
||||
|
||||
self._operation = data.get("Operation")
|
||||
self._last_error = data.get("LastError")
|
||||
self._compatible = data.get("Compatible")
|
||||
self._variant = data.get("Variant")
|
||||
self._boot_slot = data.get("BootSlot")
|
||||
self._operation = data.get(DBUS_ATTR_OPERATION)
|
||||
self._last_error = data.get(DBUS_ATTR_LAST_ERROR)
|
||||
self._compatible = data.get(DBUS_ATTR_COMPATIBLE)
|
||||
self._variant = data.get(DBUS_ATTR_VARIANT)
|
||||
self._boot_slot = data.get(DBUS_ATTR_BOOT_SLOT)
|
||||
|
|
|
@ -3,14 +3,12 @@ import logging
|
|||
|
||||
from ..exceptions import DBusError, DBusInterfaceError
|
||||
from ..utils.gdbus import DBus
|
||||
from .const import DBUS_NAME_SYSTEMD, DBUS_OBJECT_SYSTEMD
|
||||
from .interface import DBusInterface
|
||||
from .utils import dbus_connected
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
DBUS_NAME = "org.freedesktop.systemd1"
|
||||
DBUS_OBJECT = "/org/freedesktop/systemd1"
|
||||
|
||||
|
||||
class Systemd(DBusInterface):
|
||||
"""Systemd function handler."""
|
||||
|
@ -18,7 +16,7 @@ class Systemd(DBusInterface):
|
|||
async def connect(self):
|
||||
"""Connect to D-Bus."""
|
||||
try:
|
||||
self.dbus = await DBus.connect(DBUS_NAME, DBUS_OBJECT)
|
||||
self.dbus = await DBus.connect(DBUS_NAME_SYSTEMD, DBUS_OBJECT_SYSTEMD)
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't connect to systemd")
|
||||
except DBusInterfaceError:
|
||||
|
|
|
@ -89,7 +89,7 @@ class HostManager(CoreSysAttributes):
|
|||
if self.sys_dbus.systemd.is_connected:
|
||||
await self.services.update()
|
||||
|
||||
if self.sys_dbus.nmi_dns.is_connected:
|
||||
if self.sys_dbus.network.is_connected:
|
||||
await self.network.update()
|
||||
|
||||
with suppress(PulseAudioError):
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""Info control for host."""
|
||||
import logging
|
||||
from typing import List
|
||||
from typing import Dict, List
|
||||
|
||||
from supervisor.dbus.network.interface import NetworkInterface
|
||||
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import DBusError, DBusNotConnectedError, HostNotSupportedError
|
||||
|
@ -15,12 +17,17 @@ class NetworkManager(CoreSysAttributes):
|
|||
"""Initialize system center handling."""
|
||||
self.coresys: CoreSys = coresys
|
||||
|
||||
@property
|
||||
def interfaces(self) -> Dict[str, NetworkInterface]:
|
||||
"""Return a dictionary of active interfaces."""
|
||||
return self.sys_dbus.network.interfaces
|
||||
|
||||
@property
|
||||
def dns_servers(self) -> List[str]:
|
||||
"""Return a list of local DNS servers."""
|
||||
# Read all local dns servers
|
||||
servers: List[str] = []
|
||||
for config in self.sys_dbus.nmi_dns.configuration:
|
||||
for config in self.sys_dbus.network.dns.configuration:
|
||||
if config.vpn or not config.nameservers:
|
||||
continue
|
||||
servers.extend(config.nameservers)
|
||||
|
@ -29,11 +36,11 @@ class NetworkManager(CoreSysAttributes):
|
|||
|
||||
async def update(self):
|
||||
"""Update properties over dbus."""
|
||||
_LOGGER.info("Update local network DNS information")
|
||||
_LOGGER.info("Update local network information")
|
||||
try:
|
||||
await self.sys_dbus.nmi_dns.update()
|
||||
await self.sys_dbus.network.update()
|
||||
except DBusError:
|
||||
_LOGGER.warning("Can't update host DNS system information!")
|
||||
_LOGGER.warning("Can't update network information!")
|
||||
except DBusNotConnectedError as err:
|
||||
_LOGGER.error("No hostname D-Bus connection available")
|
||||
raise HostNotSupportedError() from err
|
||||
|
|
|
@ -22,7 +22,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
|||
# Use to convert GVariant into json
|
||||
RE_GVARIANT_TYPE: re.Pattern[Any] = re.compile(
|
||||
r"\"[^\"\\]*(?:\\.[^\"\\]*)*\"|(boolean|byte|int16|uint16|int32|uint32|handle|int64|uint64|double|"
|
||||
r"string|objectpath|signature|@[asviumodf\{\}]+) "
|
||||
r"string|objectpath|signature|@[asviumodfy\{\}\(\)]+) "
|
||||
)
|
||||
RE_GVARIANT_VARIANT: re.Pattern[Any] = re.compile(r"\"[^\"\\]*(?:\\.[^\"\\]*)*\"|(<|>)")
|
||||
RE_GVARIANT_STRING_ESC: re.Pattern[Any] = re.compile(
|
||||
|
@ -73,7 +73,7 @@ class DBus:
|
|||
# pylint: disable=protected-access
|
||||
await self._init_proxy()
|
||||
|
||||
_LOGGER.info("Connect to dbus: %s - %s", bus_name, object_path)
|
||||
_LOGGER.debug("Connect to dbus: %s - %s", bus_name, object_path)
|
||||
return self
|
||||
|
||||
async def _init_proxy(self) -> None:
|
||||
|
@ -167,7 +167,7 @@ class DBus:
|
|||
)
|
||||
|
||||
# Run command
|
||||
_LOGGER.info("Call %s on %s", method, self.object_path)
|
||||
_LOGGER.debug("Call %s on %s", method, self.object_path)
|
||||
data = await self._send(command)
|
||||
|
||||
# Parse and return data
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
"""Test NetwrokInterface API."""
|
||||
import pytest
|
||||
|
||||
from tests.const import TEST_INTERFACE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_network_info(api_client):
|
||||
"""Test network manager api."""
|
||||
resp = await api_client.get("/network/info")
|
||||
result = await resp.json()
|
||||
assert TEST_INTERFACE in result["data"]["interfaces"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_network_interface_info(api_client):
|
||||
"""Test network manager api."""
|
||||
resp = await api_client.get(f"/network/interface/{TEST_INTERFACE}/info")
|
||||
result = await resp.json()
|
||||
assert result["data"]["ip_address"] == "192.168.2.148/24"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_network_interface_update(api_client):
|
||||
"""Test network manager api."""
|
||||
resp = await api_client.post(
|
||||
f"/network/interface/{TEST_INTERFACE}/update",
|
||||
json={"method": "static", "dns": ["1.1.1.1"], "address": "192.168.2.148/24"},
|
||||
)
|
||||
result = await resp.json()
|
||||
assert result["result"] == "ok"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_network_interface_info_invalid(api_client):
|
||||
"""Test network manager api."""
|
||||
resp = await api_client.get("/network/interface/invalid/info")
|
||||
result = await resp.json()
|
||||
assert not result["data"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_network_interface_update_invalid(api_client):
|
||||
"""Test network manager api."""
|
||||
resp = await api_client.post("/network/interface/invalid/update", json={})
|
||||
result = await resp.json()
|
||||
assert result["message"] == "Interface invalid does not exsist"
|
||||
|
||||
resp = await api_client.post(f"/network/interface/{TEST_INTERFACE}/update", json={})
|
||||
result = await resp.json()
|
||||
assert result["message"] == "You need to supply at least one option to update"
|
||||
|
||||
resp = await api_client.post(
|
||||
f"/network/interface/{TEST_INTERFACE}/update", json={"dns": "1.1.1.1"}
|
||||
)
|
||||
result = await resp.json()
|
||||
assert (
|
||||
result["message"]
|
||||
== "expected a list for dictionary value @ data['dns']. Got '1.1.1.1'"
|
||||
)
|
|
@ -3,7 +3,13 @@ import json
|
|||
from pathlib import Path
|
||||
|
||||
|
||||
def load_json_fixture(filename):
|
||||
"""Load a fixture."""
|
||||
def load_json_fixture(filename: str) -> dict:
|
||||
"""Load a json fixture."""
|
||||
path = Path(Path(__file__).parent.joinpath("fixtures"), filename)
|
||||
return json.loads(path.read_text())
|
||||
|
||||
|
||||
def load_fixture(filename: str) -> str:
|
||||
"""Load a fixture."""
|
||||
path = Path(Path(__file__).parent.joinpath("fixtures"), filename)
|
||||
return path.read_text()
|
||||
|
|
|
@ -2,16 +2,25 @@
|
|||
from unittest.mock import MagicMock, PropertyMock, patch
|
||||
from uuid import uuid4
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp.test_utils import TestClient
|
||||
import pytest
|
||||
|
||||
from supervisor.api import RestAPI
|
||||
from supervisor.bootstrap import initialize_coresys
|
||||
from supervisor.coresys import CoreSys
|
||||
from supervisor.dbus.const import DBUS_NAME_NM, DBUS_OBJECT_BASE
|
||||
from supervisor.dbus.network import NetworkManager
|
||||
from supervisor.docker import DockerAPI
|
||||
from supervisor.utils.gdbus import DBus
|
||||
|
||||
from tests.common import load_fixture, load_json_fixture
|
||||
|
||||
# pylint: disable=redefined-outer-name, protected-access
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def docker():
|
||||
def docker() -> DockerAPI:
|
||||
"""Mock DockerAPI."""
|
||||
images = [MagicMock(tags=["homeassistant/amd64-hassio-supervisor:latest"])]
|
||||
|
||||
|
@ -28,12 +37,52 @@ def docker():
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
async def coresys(loop, docker):
|
||||
def dbus() -> DBus:
|
||||
"""Mock DBUS."""
|
||||
|
||||
async def mock_get_properties(_, interface):
|
||||
return load_json_fixture(f"{interface.replace('.', '_')}.json")
|
||||
|
||||
async def mock_send(_, command):
|
||||
filetype = "xml" if "--xml" in command else "fixture"
|
||||
fixture = f"{command[6].replace('/', '_')[1:]}.{filetype}"
|
||||
return load_fixture(fixture)
|
||||
|
||||
with patch("supervisor.utils.gdbus.DBus._send", new=mock_send), patch(
|
||||
"supervisor.dbus.interface.DBusInterface.is_connected", return_value=True,
|
||||
), patch("supervisor.utils.gdbus.DBus.get_properties", new=mock_get_properties):
|
||||
|
||||
dbus_obj = DBus(DBUS_NAME_NM, DBUS_OBJECT_BASE)
|
||||
|
||||
yield dbus_obj
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def network_manager(dbus) -> NetworkManager:
|
||||
"""Mock NetworkManager."""
|
||||
|
||||
async def dns_update():
|
||||
pass
|
||||
|
||||
with patch("supervisor.dbus.network.NetworkManager.dns", return_value=MagicMock()):
|
||||
nm_obj = NetworkManager()
|
||||
nm_obj.dns.update = dns_update
|
||||
nm_obj.dbus = dbus
|
||||
await nm_obj.connect()
|
||||
await nm_obj.update()
|
||||
|
||||
yield nm_obj
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def coresys(loop, docker, dbus, network_manager, aiohttp_client) -> CoreSys:
|
||||
"""Create a CoreSys Mock."""
|
||||
with patch("supervisor.bootstrap.initialize_system_data"), patch(
|
||||
"supervisor.bootstrap.setup_diagnostics"
|
||||
), patch(
|
||||
"supervisor.bootstrap.fetch_timezone", return_value="Europe/Zurich",
|
||||
), patch(
|
||||
"aiohttp.ClientSession", return_value=TestClient.session,
|
||||
):
|
||||
coresys_obj = await initialize_coresys()
|
||||
|
||||
|
@ -42,6 +91,8 @@ async def coresys(loop, docker):
|
|||
|
||||
coresys_obj._machine = "qemux86-64"
|
||||
coresys_obj._machine_id = uuid4()
|
||||
coresys_obj._dbus = dbus
|
||||
coresys_obj._dbus.network = network_manager
|
||||
|
||||
yield coresys_obj
|
||||
|
||||
|
@ -61,3 +112,12 @@ def sys_supervisor():
|
|||
) as mock:
|
||||
mock.return_value = MagicMock()
|
||||
yield MagicMock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def api_client(aiohttp_client, coresys):
|
||||
"""Fixture for RestAPI client."""
|
||||
api = RestAPI(coresys)
|
||||
api.webapp = web.Application()
|
||||
await api.load()
|
||||
yield await aiohttp_client(api.webapp)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
"""Consts for tests."""
|
||||
|
||||
TEST_INTERFACE = "eth0"
|
|
@ -0,0 +1,15 @@
|
|||
"""Test NetwrokInterface."""
|
||||
import pytest
|
||||
|
||||
from supervisor.dbus.network import NetworkManager
|
||||
|
||||
from tests.const import TEST_INTERFACE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_network_interface(network_manager: NetworkManager):
|
||||
"""Test network interface."""
|
||||
interface = network_manager.interfaces[TEST_INTERFACE]
|
||||
assert interface.name == TEST_INTERFACE
|
||||
assert interface.connection.state == 2
|
||||
assert interface.connection.uuid == "0c23631e-2118-355c-bbb0-8943229cb0d6"
|
|
@ -0,0 +1,12 @@
|
|||
"""Test NetwrokInterface."""
|
||||
import pytest
|
||||
|
||||
from supervisor.dbus.network import NetworkManager
|
||||
|
||||
from tests.const import TEST_INTERFACE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_network_manager(network_manager: NetworkManager):
|
||||
"""Test network manager update."""
|
||||
assert TEST_INTERFACE in network_manager.interfaces
|
|
@ -0,0 +1,12 @@
|
|||
"""Test network utils."""
|
||||
from supervisor.dbus.network.utils import int2ip, ip2int
|
||||
|
||||
|
||||
def test_int2ip():
|
||||
"""Test int2ip."""
|
||||
assert int2ip(16885952) == "192.168.1.1"
|
||||
|
||||
|
||||
def test_ip2int():
|
||||
"""Test ip2int."""
|
||||
assert ip2int("192.168.1.1") == 16885952
|
|
@ -0,0 +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} {}>}},)
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"Devices": ["/org/freedesktop/NetworkManager/Devices/1"],
|
||||
"AllDevices": [
|
||||
"/org/freedesktop/NetworkManager/Devices/1",
|
||||
"/org/freedesktop/NetworkManager/Devices/2"
|
||||
],
|
||||
"Checkpoints": [],
|
||||
"NetworkingEnabled": true,
|
||||
"WirelessEnabled": true,
|
||||
"WirelessHardwareEnabled": true,
|
||||
"WwanEnabled": true,
|
||||
"WwanHardwareEnabled": true,
|
||||
"WimaxEnabled": false,
|
||||
"WimaxHardwareEnabled": false,
|
||||
"ActiveConnections": ["/org/freedesktop/NetworkManager/ActiveConnection/1"],
|
||||
"PrimaryConnection": "/org/freedesktop/NetworkManager/ActiveConnection/1",
|
||||
"PrimaryConnectionType": "802-3-ethernet",
|
||||
"Metered": 4,
|
||||
"ActivatingConnection": "/",
|
||||
"Startup": false,
|
||||
"Version": "1.22.10",
|
||||
"Capabilities": [1],
|
||||
"State": 70,
|
||||
"Connectivity": 4,
|
||||
"ConnectivityCheckAvailable": true,
|
||||
"ConnectivityCheckEnabled": true,
|
||||
"ConnectivityCheckUri": "http://connectivity-check.ubuntu.com/",
|
||||
"GlobalDnsConfiguration": {}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager">
|
||||
<method name="Reload">
|
||||
<arg type="u" name="flags" direction="in"/>
|
||||
</method>
|
||||
<method name="GetDevices">
|
||||
<arg type="ao" name="devices" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAllDevices">
|
||||
<arg type="ao" name="devices" direction="out"/>
|
||||
</method>
|
||||
<method name="GetDeviceByIpIface">
|
||||
<arg type="s" name="iface" direction="in"/>
|
||||
<arg type="o" name="device" direction="out"/>
|
||||
</method>
|
||||
<method name="ActivateConnection">
|
||||
<arg type="o" name="connection" direction="in"/>
|
||||
<arg type="o" name="device" direction="in"/>
|
||||
<arg type="o" name="specific_object" direction="in"/>
|
||||
<arg type="o" name="active_connection" direction="out"/>
|
||||
</method>
|
||||
<method name="AddAndActivateConnection">
|
||||
<arg type="a{sa{sv}}" name="connection" direction="in"/>
|
||||
<arg type="o" name="device" direction="in"/>
|
||||
<arg type="o" name="specific_object" direction="in"/>
|
||||
<arg type="o" name="path" direction="out"/>
|
||||
<arg type="o" name="active_connection" direction="out"/>
|
||||
</method>
|
||||
<method name="AddAndActivateConnection2">
|
||||
<arg type="a{sa{sv}}" name="connection" direction="in"/>
|
||||
<arg type="o" name="device" direction="in"/>
|
||||
<arg type="o" name="specific_object" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="path" direction="out"/>
|
||||
<arg type="o" name="active_connection" direction="out"/>
|
||||
<arg type="a{sv}" name="result" direction="out"/>
|
||||
</method>
|
||||
<method name="DeactivateConnection">
|
||||
<arg type="o" name="active_connection" direction="in"/>
|
||||
</method>
|
||||
<method name="Sleep">
|
||||
<arg type="b" name="sleep" direction="in"/>
|
||||
</method>
|
||||
<method name="Enable">
|
||||
<arg type="b" name="enable" direction="in"/>
|
||||
</method>
|
||||
<method name="GetPermissions">
|
||||
<arg type="a{ss}" name="permissions" direction="out"/>
|
||||
</method>
|
||||
<method name="SetLogging">
|
||||
<arg type="s" name="level" direction="in"/>
|
||||
<arg type="s" name="domains" direction="in"/>
|
||||
</method>
|
||||
<method name="GetLogging">
|
||||
<arg type="s" name="level" direction="out"/>
|
||||
<arg type="s" name="domains" direction="out"/>
|
||||
</method>
|
||||
<method name="CheckConnectivity">
|
||||
<arg type="u" name="connectivity" direction="out"/>
|
||||
</method>
|
||||
<method name="state">
|
||||
<arg type="u" name="state" direction="out"/>
|
||||
</method>
|
||||
<method name="CheckpointCreate">
|
||||
<arg type="ao" name="devices" direction="in"/>
|
||||
<arg type="u" name="rollback_timeout" direction="in"/>
|
||||
<arg type="u" name="flags" direction="in"/>
|
||||
<arg type="o" name="checkpoint" direction="out"/>
|
||||
</method>
|
||||
<method name="CheckpointDestroy">
|
||||
<arg type="o" name="checkpoint" direction="in"/>
|
||||
</method>
|
||||
<method name="CheckpointRollback">
|
||||
<arg type="o" name="checkpoint" direction="in"/>
|
||||
<arg type="a{su}" name="result" direction="out"/>
|
||||
</method>
|
||||
<method name="CheckpointAdjustRollbackTimeout">
|
||||
<arg type="o" name="checkpoint" direction="in"/>
|
||||
<arg type="u" name="add_timeout" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<signal name="CheckPermissions"/>
|
||||
<signal name="StateChanged">
|
||||
<arg type="u" name="state"/>
|
||||
</signal>
|
||||
<signal name="DeviceAdded">
|
||||
<arg type="o" name="device_path"/>
|
||||
</signal>
|
||||
<signal name="DeviceRemoved">
|
||||
<arg type="o" name="device_path"/>
|
||||
</signal>
|
||||
<property type="ao" name="Devices" access="read"/>
|
||||
<property type="ao" name="AllDevices" access="read"/>
|
||||
<property type="ao" name="Checkpoints" access="read"/>
|
||||
<property type="b" name="NetworkingEnabled" access="read"/>
|
||||
<property type="b" name="WirelessEnabled" access="readwrite"/>
|
||||
<property type="b" name="WirelessHardwareEnabled" access="read"/>
|
||||
<property type="b" name="WwanEnabled" access="readwrite"/>
|
||||
<property type="b" name="WwanHardwareEnabled" access="read"/>
|
||||
<property type="b" name="WimaxEnabled" access="readwrite"/>
|
||||
<property type="b" name="WimaxHardwareEnabled" access="read"/>
|
||||
<property type="ao" name="ActiveConnections" access="read"/>
|
||||
<property type="o" name="PrimaryConnection" access="read"/>
|
||||
<property type="s" name="PrimaryConnectionType" access="read"/>
|
||||
<property type="u" name="Metered" access="read"/>
|
||||
<property type="o" name="ActivatingConnection" access="read"/>
|
||||
<property type="b" name="Startup" access="read"/>
|
||||
<property type="s" name="Version" access="read"/>
|
||||
<property type="u" name="Capabilities" access="read"/>
|
||||
<property type="u" name="State" access="read"/>
|
||||
<property type="u" name="Connectivity" access="read"/>
|
||||
<property type="b" name="ConnectivityCheckAvailable" access="read"/>
|
||||
<property type="b" name="ConnectivityCheckEnabled" access="readwrite"/>
|
||||
<property type="s" name="ConnectivityCheckUri" access="read"/>
|
||||
<property type="a{sv}" name="GlobalDnsConfiguration" access="readwrite"/>
|
||||
</interface>
|
||||
<node name="IP4Config"/>
|
||||
<node name="ActiveConnection"/>
|
||||
<node name="AgentManager"/>
|
||||
<node name="Devices"/>
|
||||
<node name="DHCP4Config"/>
|
||||
<node name="DnsManager"/>
|
||||
<node name="IP6Config"/>
|
||||
<node name="Settings"/>
|
||||
</node>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.Connection.Active">
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<signal name="StateChanged">
|
||||
<arg type="u" name="state"/>
|
||||
<arg type="u" name="reason"/>
|
||||
</signal>
|
||||
<property type="o" name="Connection" access="read"/>
|
||||
<property type="o" name="SpecificObject" access="read"/>
|
||||
<property type="s" name="Id" access="read"/>
|
||||
<property type="s" name="Uuid" access="read"/>
|
||||
<property type="s" name="Type" access="read"/>
|
||||
<property type="ao" name="Devices" access="read"/>
|
||||
<property type="u" name="State" access="read"/>
|
||||
<property type="u" name="StateFlags" access="read"/>
|
||||
<property type="b" name="Default" access="read"/>
|
||||
<property type="o" name="Ip4Config" access="read"/>
|
||||
<property type="o" name="Dhcp4Config" access="read"/>
|
||||
<property type="b" name="Default6" access="read"/>
|
||||
<property type="o" name="Ip6Config" access="read"/>
|
||||
<property type="o" name="Dhcp6Config" access="read"/>
|
||||
<property type="b" name="Vpn" access="read"/>
|
||||
<property type="o" name="Master" access="read"/>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"Connection": "/org/freedesktop/NetworkManager/Settings/1",
|
||||
"SpecificObject": "/",
|
||||
"Id": "Wired connection 1",
|
||||
"Uuid": "0c23631e-2118-355c-bbb0-8943229cb0d6",
|
||||
"Type": "802-3-ethernet",
|
||||
"Devices": ["/org/freedesktop/NetworkManager/Devices/1"],
|
||||
"State": 2,
|
||||
"StateFlags": 12,
|
||||
"Default": true,
|
||||
"Ip4Config": "/org/freedesktop/NetworkManager/IP4Config/1",
|
||||
"Dhcp4Config": "/org/freedesktop/NetworkManager/DHCP4Config/1",
|
||||
"Default6": false,
|
||||
"Ip6Config": "/org/freedesktop/NetworkManager/IP6Config/1",
|
||||
"Dhcp6Config": "/",
|
||||
"Vpn": false,
|
||||
"Master": "/"
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"Udi": "/sys/devices/pci0000:00/0000:00:1f.6/net/eth0",
|
||||
"Interface": "eth0",
|
||||
"IpInterface": "eth0",
|
||||
"Driver": "e1000e",
|
||||
"DriverVersion": "3.2.6-k",
|
||||
"FirmwareVersion": "0.7-4",
|
||||
"Capabilities": 3,
|
||||
"Ip4Address": 2499979456,
|
||||
"State": 100,
|
||||
"StateReason": [100, 0],
|
||||
"ActiveConnection": "/org/freedesktop/NetworkManager/ActiveConnection/1",
|
||||
"Ip4Config": "/org/freedesktop/NetworkManager/IP4Config/1",
|
||||
"Dhcp4Config": "/org/freedesktop/NetworkManager/DHCP4Config/1",
|
||||
"Ip6Config": "/org/freedesktop/NetworkManager/IP6Config/1",
|
||||
"Dhcp6Config": "/",
|
||||
"Managed": true,
|
||||
"Autoconnect": true,
|
||||
"FirmwareMissing": false,
|
||||
"NmPluginMissing": false,
|
||||
"DeviceType": 1,
|
||||
"AvailableConnections": ["/org/freedesktop/NetworkManager/Settings/1"],
|
||||
"PhysicalPortId": "",
|
||||
"Mtu": 1500,
|
||||
"Metered": 4,
|
||||
"LldpNeighbors": [],
|
||||
"Real": true,
|
||||
"Ip4Connectivity": 4,
|
||||
"Ip6Connectivity": 3,
|
||||
"InterfaceFlags": 65539
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.Device.Statistics">
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<property type="u" name="RefreshRateMs" access="readwrite"/>
|
||||
<property type="t" name="TxBytes" access="read"/>
|
||||
<property type="t" name="RxBytes" access="read"/>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.Device">
|
||||
<method name="Reapply">
|
||||
<arg type="a{sa{sv}}" name="connection" direction="in"/>
|
||||
<arg type="t" name="version_id" direction="in"/>
|
||||
<arg type="u" name="flags" direction="in"/>
|
||||
</method>
|
||||
<method name="GetAppliedConnection">
|
||||
<arg type="u" name="flags" direction="in"/>
|
||||
<arg type="a{sa{sv}}" name="connection" direction="out"/>
|
||||
<arg type="t" name="version_id" direction="out"/>
|
||||
</method>
|
||||
<method name="Disconnect"/>
|
||||
<method name="Delete"/>
|
||||
<signal name="StateChanged">
|
||||
<arg type="u" name="new_state"/>
|
||||
<arg type="u" name="old_state"/>
|
||||
<arg type="u" name="reason"/>
|
||||
</signal>
|
||||
<property type="s" name="Udi" access="read"/>
|
||||
<property type="s" name="Interface" access="read"/>
|
||||
<property type="s" name="IpInterface" access="read"/>
|
||||
<property type="s" name="Driver" access="read"/>
|
||||
<property type="s" name="DriverVersion" access="read"/>
|
||||
<property type="s" name="FirmwareVersion" access="read"/>
|
||||
<property type="u" name="Capabilities" access="read"/>
|
||||
<property type="u" name="Ip4Address" access="read"/>
|
||||
<property type="u" name="State" access="read"/>
|
||||
<property type="(uu)" name="StateReason" access="read"/>
|
||||
<property type="o" name="ActiveConnection" access="read"/>
|
||||
<property type="o" name="Ip4Config" access="read"/>
|
||||
<property type="o" name="Dhcp4Config" access="read"/>
|
||||
<property type="o" name="Ip6Config" access="read"/>
|
||||
<property type="o" name="Dhcp6Config" access="read"/>
|
||||
<property type="b" name="Managed" access="readwrite"/>
|
||||
<property type="b" name="Autoconnect" access="readwrite"/>
|
||||
<property type="b" name="FirmwareMissing" access="read"/>
|
||||
<property type="b" name="NmPluginMissing" access="read"/>
|
||||
<property type="u" name="DeviceType" access="read"/>
|
||||
<property type="ao" name="AvailableConnections" access="read"/>
|
||||
<property type="s" name="PhysicalPortId" access="read"/>
|
||||
<property type="u" name="Mtu" access="read"/>
|
||||
<property type="u" name="Metered" access="read"/>
|
||||
<property type="aa{sv}" name="LldpNeighbors" access="read"/>
|
||||
<property type="b" name="Real" access="read"/>
|
||||
<property type="u" name="Ip4Connectivity" access="read"/>
|
||||
<property type="u" name="Ip6Connectivity" access="read"/>
|
||||
<property type="u" name="InterfaceFlags" access="read"/>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.Device.Wired">
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<property type="s" name="HwAddress" access="read"/>
|
||||
<property type="s" name="PermHwAddress" access="read"/>
|
||||
<property type="u" name="Speed" access="read"/>
|
||||
<property type="as" name="S390Subchannels" access="read"/>
|
||||
<property type="b" name="Carrier" access="read"/>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.DnsManager">
|
||||
<property type="s" name="Mode" access="read"/>
|
||||
<property type="s" name="RcManager" access="read"/>
|
||||
<property type="aa{sv}" name="Configuration" access="read"/>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Addresses": [[2499979456, 24, 16951488]],
|
||||
"AddressData": [{ "address": "192.168.2.148", "prefix": 24 }],
|
||||
"Gateway": "192.168.2.1",
|
||||
"Routes": [
|
||||
[174272, 24, 0, 100],
|
||||
[65193, 16, 0, 1000]
|
||||
],
|
||||
"RouteData": [
|
||||
{ "dest": "192.168.2.0", "prefix": 24, "metric": 100 },
|
||||
{ "dest": "169.254.0.0", "prefix": 16, "metric": 1000 },
|
||||
{ "dest": "0.0.0.0", "prefix": 0, "next-hop": "192.168.2.1", "metric": 100 }
|
||||
],
|
||||
"NameserverData": [{ "address": "192.168.2.1" }],
|
||||
"Nameservers": [16951488],
|
||||
"Domains": [],
|
||||
"Searches": [],
|
||||
"DnsOptions": [],
|
||||
"DnsPriority": 100,
|
||||
"WinsServerData": [],
|
||||
"WinsServers": []
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.IP4Config">
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<property type="aau" name="Addresses" access="read"/>
|
||||
<property type="aa{sv}" name="AddressData" access="read"/>
|
||||
<property type="s" name="Gateway" access="read"/>
|
||||
<property type="aau" name="Routes" access="read"/>
|
||||
<property type="aa{sv}" name="RouteData" access="read"/>
|
||||
<property type="aa{sv}" name="NameserverData" access="read"/>
|
||||
<property type="au" name="Nameservers" access="read"/>
|
||||
<property type="as" name="Domains" access="read"/>
|
||||
<property type="as" name="Searches" access="read"/>
|
||||
<property type="as" name="DnsOptions" access="read"/>
|
||||
<property type="i" name="DnsPriority" access="read"/>
|
||||
<property type="as" name="WinsServerData" access="read"/>
|
||||
<property type="au" name="WinsServers" access="read"/>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +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} {}>}},)
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<!-- GDBus 2.64.3 -->
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.Properties">
|
||||
<method name="Get">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="GetAll">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="a{sv}" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg type="s" name="interface_name" direction="in"/>
|
||||
<arg type="s" name="property_name" direction="in"/>
|
||||
<arg type="v" name="value" direction="in"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="s" name="interface_name"/>
|
||||
<arg type="a{sv}" name="changed_properties"/>
|
||||
<arg type="as" name="invalidated_properties"/>
|
||||
</signal>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Introspectable">
|
||||
<method name="Introspect">
|
||||
<arg type="s" name="xml_data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.DBus.Peer">
|
||||
<method name="Ping"/>
|
||||
<method name="GetMachineId">
|
||||
<arg type="s" name="machine_uuid" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
<interface name="org.freedesktop.NetworkManager.Settings.Connection">
|
||||
<method name="Update">
|
||||
<arg type="a{sa{sv}}" name="properties" direction="in"/>
|
||||
</method>
|
||||
<method name="UpdateUnsaved">
|
||||
<arg type="a{sa{sv}}" name="properties" direction="in"/>
|
||||
</method>
|
||||
<method name="Delete"/>
|
||||
<method name="GetSettings">
|
||||
<arg type="a{sa{sv}}" name="settings" direction="out"/>
|
||||
</method>
|
||||
<method name="GetSecrets">
|
||||
<arg type="s" name="setting_name" direction="in"/>
|
||||
<arg type="a{sa{sv}}" name="secrets" direction="out"/>
|
||||
</method>
|
||||
<method name="ClearSecrets"/>
|
||||
<method name="Save"/>
|
||||
<method name="Update2">
|
||||
<arg type="a{sa{sv}}" name="settings" direction="in"/>
|
||||
<arg type="u" name="flags" direction="in"/>
|
||||
<arg type="a{sv}" name="args" direction="in"/>
|
||||
<arg type="a{sv}" name="result" direction="out"/>
|
||||
</method>
|
||||
<signal name="PropertiesChanged">
|
||||
<arg type="a{sv}" name="properties"/>
|
||||
</signal>
|
||||
<signal name="Updated"/>
|
||||
<signal name="Removed"/>
|
||||
<property type="b" name="Unsaved" access="read"/>
|
||||
<property type="u" name="Flags" access="read"/>
|
||||
<property type="s" name="Filename" access="read"/>
|
||||
</interface>
|
||||
</node>
|
Loading…
Reference in New Issue