Fix reconfigure by SSDP or Zeroconf discovery in Synology DSM (#92088)
This commit is contained in:
parent
29ca43acf6
commit
4e7f39e3d0
2 changed files with 20 additions and 21 deletions
|
@ -2,7 +2,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address as ip
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
@ -38,6 +38,7 @@ from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||||
|
from homeassistant.util.network import is_ip_address as is_ip
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_DEVICE_TOKEN,
|
CONF_DEVICE_TOKEN,
|
||||||
|
@ -99,14 +100,6 @@ def _ordered_shared_schema(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _is_valid_ip(text: str) -> bool:
|
|
||||||
try:
|
|
||||||
ip_address(text)
|
|
||||||
except ValueError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def format_synology_mac(mac: str) -> str:
|
def format_synology_mac(mac: str) -> str:
|
||||||
"""Format a mac address to the format used by Synology DSM."""
|
"""Format a mac address to the format used by Synology DSM."""
|
||||||
return mac.replace(":", "").replace("-", "").upper()
|
return mac.replace(":", "").replace("-", "").upper()
|
||||||
|
@ -284,16 +277,12 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
break
|
break
|
||||||
self._abort_if_unique_id_configured()
|
self._abort_if_unique_id_configured()
|
||||||
|
|
||||||
fqdn_with_ssl_verification = (
|
|
||||||
existing_entry
|
|
||||||
and not _is_valid_ip(existing_entry.data[CONF_HOST])
|
|
||||||
and existing_entry.data[CONF_VERIFY_SSL]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
existing_entry
|
existing_entry
|
||||||
|
and is_ip(existing_entry.data[CONF_HOST])
|
||||||
|
and is_ip(host)
|
||||||
and existing_entry.data[CONF_HOST] != host
|
and existing_entry.data[CONF_HOST] != host
|
||||||
and not fqdn_with_ssl_verification
|
and ip(existing_entry.data[CONF_HOST]).version == ip(host).version
|
||||||
):
|
):
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"Update host from '%s' to '%s' for NAS '%s' via discovery",
|
"Update host from '%s' to '%s' for NAS '%s' via discovery",
|
||||||
|
|
|
@ -512,7 +512,7 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None:
|
||||||
MockConfigEntry(
|
MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
data={
|
data={
|
||||||
CONF_HOST: "wrong_host",
|
CONF_HOST: "192.168.1.3",
|
||||||
CONF_VERIFY_SSL: VERIFY_SSL,
|
CONF_VERIFY_SSL: VERIFY_SSL,
|
||||||
CONF_USERNAME: USERNAME,
|
CONF_USERNAME: USERNAME,
|
||||||
CONF_PASSWORD: PASSWORD,
|
CONF_PASSWORD: PASSWORD,
|
||||||
|
@ -539,14 +539,24 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_setup_entry")
|
@pytest.mark.usefixtures("mock_setup_entry")
|
||||||
async def test_skip_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None:
|
@pytest.mark.parametrize(
|
||||||
|
("current_host", "new_host"),
|
||||||
|
[
|
||||||
|
("some.fqdn", "192.168.1.5"),
|
||||||
|
("192.168.1.5", "abcd:1234::"),
|
||||||
|
("abcd:1234::", "192.168.1.5"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_skip_reconfig_ssdp(
|
||||||
|
hass: HomeAssistant, current_host: str, new_host: str, service: MagicMock
|
||||||
|
) -> None:
|
||||||
"""Test re-configuration of already existing entry by ssdp."""
|
"""Test re-configuration of already existing entry by ssdp."""
|
||||||
|
|
||||||
MockConfigEntry(
|
MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
data={
|
data={
|
||||||
CONF_HOST: "wrong_host",
|
CONF_HOST: current_host,
|
||||||
CONF_VERIFY_SSL: True,
|
CONF_VERIFY_SSL: VERIFY_SSL,
|
||||||
CONF_USERNAME: USERNAME,
|
CONF_USERNAME: USERNAME,
|
||||||
CONF_PASSWORD: PASSWORD,
|
CONF_PASSWORD: PASSWORD,
|
||||||
CONF_MAC: MACS,
|
CONF_MAC: MACS,
|
||||||
|
@ -560,7 +570,7 @@ async def test_skip_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> No
|
||||||
data=ssdp.SsdpServiceInfo(
|
data=ssdp.SsdpServiceInfo(
|
||||||
ssdp_usn="mock_usn",
|
ssdp_usn="mock_usn",
|
||||||
ssdp_st="mock_st",
|
ssdp_st="mock_st",
|
||||||
ssdp_location="http://192.168.1.5:5000",
|
ssdp_location=f"http://{new_host}:5000",
|
||||||
upnp={
|
upnp={
|
||||||
ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm",
|
ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm",
|
||||||
ssdp.ATTR_UPNP_SERIAL: "001132XXXX59", # Existing in MACS[0], but SSDP does not have `-`
|
ssdp.ATTR_UPNP_SERIAL: "001132XXXX59", # Existing in MACS[0], but SSDP does not have `-`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue