Allow to add a description for a port (#1023)

This commit is contained in:
Pascal Vizeli 2019-04-09 22:15:23 +02:00 committed by GitHub
parent 45b4800378
commit b77146a4e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 35 deletions

1
API.md
View File

@ -480,6 +480,7 @@ Get all available addons.
"build": "bool", "build": "bool",
"options": "{}", "options": "{}",
"network": "{}|null", "network": "{}|null",
"network_description": "{}|null",
"host_network": "bool", "host_network": "bool",
"host_pid": "bool", "host_pid": "bool",
"host_ipc": "bool", "host_ipc": "bool",

View File

@ -56,6 +56,7 @@ from ..const import (
ATTR_NETWORK, ATTR_NETWORK,
ATTR_OPTIONS, ATTR_OPTIONS,
ATTR_PORTS, ATTR_PORTS,
ATTR_PORTS_DESCRIPTION,
ATTR_PRIVILEGED, ATTR_PRIVILEGED,
ATTR_PROTECTED, ATTR_PROTECTED,
ATTR_REPOSITORY, ATTR_REPOSITORY,
@ -364,10 +365,15 @@ class Addon(CoreSysAttributes):
"""Return list of discoverable components/platforms.""" """Return list of discoverable components/platforms."""
return self._mesh.get(ATTR_DISCOVERY, []) return self._mesh.get(ATTR_DISCOVERY, [])
@property
def ports_description(self):
"""Return descriptions of ports."""
return self._mesh.get(ATTR_PORTS_DESCRIPTION)
@property @property
def ports(self): def ports(self):
"""Return ports of add-on.""" """Return ports of add-on."""
if self.host_network or ATTR_PORTS not in self._mesh: if ATTR_PORTS not in self._mesh:
return None return None
if not self.is_installed or \ if not self.is_installed or \
@ -380,13 +386,15 @@ class Addon(CoreSysAttributes):
"""Set custom ports of add-on.""" """Set custom ports of add-on."""
if value is None: if value is None:
self._data.user[self._id].pop(ATTR_NETWORK, None) self._data.user[self._id].pop(ATTR_NETWORK, None)
else: return
new_ports = {}
for container_port, host_port in value.items():
if container_port in self._mesh.get(ATTR_PORTS, {}):
new_ports[container_port] = host_port
self._data.user[self._id][ATTR_NETWORK] = new_ports # Secure map ports to value
new_ports = {}
for container_port, host_port in value.items():
if container_port in self._mesh.get(ATTR_PORTS, {}):
new_ports[container_port] = host_port
self._data.user[self._id][ATTR_NETWORK] = new_ports
@property @property
def ingress_url(self): def ingress_url(self):

View File

@ -30,8 +30,8 @@ from ..const import (
ATTR_GPIO, ATTR_GPIO,
ATTR_HASSIO_API, ATTR_HASSIO_API,
ATTR_HASSIO_ROLE, ATTR_HASSIO_ROLE,
ATTR_HOMEASSISTANT_API,
ATTR_HOMEASSISTANT, ATTR_HOMEASSISTANT,
ATTR_HOMEASSISTANT_API,
ATTR_HOST_DBUS, ATTR_HOST_DBUS,
ATTR_HOST_IPC, ATTR_HOST_IPC,
ATTR_HOST_NETWORK, ATTR_HOST_NETWORK,
@ -51,6 +51,7 @@ from ..const import (
ATTR_NETWORK, ATTR_NETWORK,
ATTR_OPTIONS, ATTR_OPTIONS,
ATTR_PORTS, ATTR_PORTS,
ATTR_PORTS_DESCRIPTION,
ATTR_PRIVILEGED, ATTR_PRIVILEGED,
ATTR_PROTECTED, ATTR_PROTECTED,
ATTR_REPOSITORY, ATTR_REPOSITORY,
@ -81,7 +82,14 @@ from ..const import (
STATE_STOPPED, STATE_STOPPED,
) )
from ..discovery.validate import valid_discovery_service from ..discovery.validate import valid_discovery_service
from ..validate import ALSA_DEVICE, DOCKER_PORTS, NETWORK_PORT, TOKEN, UUID_MATCH from ..validate import (
ALSA_DEVICE,
DOCKER_PORTS,
DOCKER_PORTS_DESCRIPTION,
NETWORK_PORT,
TOKEN,
UUID_MATCH,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -145,6 +153,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
vol.Required(ATTR_BOOT): vol.Required(ATTR_BOOT):
vol.In([BOOT_AUTO, BOOT_MANUAL]), vol.In([BOOT_AUTO, BOOT_MANUAL]),
vol.Optional(ATTR_PORTS): DOCKER_PORTS, vol.Optional(ATTR_PORTS): DOCKER_PORTS,
vol.Optional(ATTR_PORTS_DESCRIPTION): DOCKER_PORTS_DESCRIPTION,
vol.Optional(ATTR_WEBUI): vol.Optional(ATTR_WEBUI):
vol.Match(r"^(?:https?|\[PROTO:\w+\]):\/\/\[HOST\]:\[PORT:\d+\].*$"), vol.Match(r"^(?:https?|\[PROTO:\w+\]):\/\/\[HOST\]:\[PORT:\d+\].*$"),
vol.Optional(ATTR_INGRESS, default=False): vol.Boolean(), vol.Optional(ATTR_INGRESS, default=False): vol.Boolean(),

View File

@ -58,6 +58,7 @@ from ..const import (
ATTR_MEMORY_USAGE, ATTR_MEMORY_USAGE,
ATTR_NAME, ATTR_NAME,
ATTR_NETWORK, ATTR_NETWORK,
ATTR_NETWORK_DESCRIPTION,
ATTR_NETWORK_RX, ATTR_NETWORK_RX,
ATTR_NETWORK_TX, ATTR_NETWORK_TX,
ATTR_OPTIONS, ATTR_OPTIONS,
@ -194,6 +195,7 @@ class APIAddons(CoreSysAttributes):
ATTR_AVAILABLE: addon.available, ATTR_AVAILABLE: addon.available,
ATTR_BUILD: addon.need_build, ATTR_BUILD: addon.need_build,
ATTR_NETWORK: addon.ports, ATTR_NETWORK: addon.ports,
ATTR_NETWORK_DESCRIPTION: addon.ports_description,
ATTR_HOST_NETWORK: addon.host_network, ATTR_HOST_NETWORK: addon.host_network,
ATTR_HOST_PID: addon.host_pid, ATTR_HOST_PID: addon.host_pid,
ATTR_HOST_IPC: addon.host_ipc, ATTR_HOST_IPC: addon.host_ipc,

View File

@ -92,6 +92,7 @@ ATTR_DESCRIPTON = "description"
ATTR_STARTUP = "startup" ATTR_STARTUP = "startup"
ATTR_BOOT = "boot" ATTR_BOOT = "boot"
ATTR_PORTS = "ports" ATTR_PORTS = "ports"
ATTR_PORTS_DESCRIPTION = "ports_description"
ATTR_PORT = "port" ATTR_PORT = "port"
ATTR_SSL = "ssl" ATTR_SSL = "ssl"
ATTR_MAP = "map" ATTR_MAP = "map"
@ -122,6 +123,7 @@ ATTR_HOST_PID = "host_pid"
ATTR_HOST_IPC = "host_ipc" ATTR_HOST_IPC = "host_ipc"
ATTR_HOST_DBUS = "host_dbus" ATTR_HOST_DBUS = "host_dbus"
ATTR_NETWORK = "network" ATTR_NETWORK = "network"
ATTR_NETWORK_DESCRIPTION = "network_description"
ATTR_TMPFS = "tmpfs" ATTR_TMPFS = "tmpfs"
ATTR_PRIVILEGED = "privileged" ATTR_PRIVILEGED = "privileged"
ATTR_USER = "user" ATTR_USER = "user"

View File

@ -147,7 +147,7 @@ class DockerAddon(DockerInterface):
@property @property
def ports(self) -> Optional[Dict[str, Union[str, int, None]]]: def ports(self) -> Optional[Dict[str, Union[str, int, None]]]:
"""Filter None from add-on ports.""" """Filter None from add-on ports."""
if not self.addon.ports: if self.addon.host_network or not self.addon.ports:
return None return None
return { return {

View File

@ -61,36 +61,18 @@ def validate_repository(repository):
REPOSITORIES = vol.All([validate_repository], vol.Unique()) REPOSITORIES = vol.All([validate_repository], vol.Unique())
# pylint: disable=inconsistent-return-statements
def convert_to_docker_ports(data):
"""Convert data into Docker port list."""
# dynamic ports
if data is None:
return None
# single port
if isinstance(data, int):
return NETWORK_PORT(data)
# port list
if isinstance(data, list) and len(data) > 2:
return vol.Schema([NETWORK_PORT])(data)
# ip port mapping
if isinstance(data, list) and len(data) == 2:
return (vol.Coerce(str)(data[0]), NETWORK_PORT(data[1]))
raise vol.Invalid("Can't validate Docker host settings")
DOCKER_PORTS = vol.Schema( DOCKER_PORTS = vol.Schema(
{ {
vol.All( vol.All(vol.Coerce(str), vol.Match(r"^\d+(?:/tcp|/udp)?$")): vol.Maybe(
vol.Coerce(str), vol.Match(r"^\d+(?:/tcp|/udp)?$") NETWORK_PORT
): convert_to_docker_ports )
} }
) )
DOCKER_PORTS_DESCRIPTION = vol.Schema(
{vol.All(vol.Coerce(str), vol.Match(r"^\d+(?:/tcp|/udp)?$")): vol.Coerce(str)}
)
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
SCHEMA_HASS_CONFIG = vol.Schema( SCHEMA_HASS_CONFIG = vol.Schema(