Provide workaround for missing/disabled/broken IPv6 (#37887)
parent
53d6f4948e
commit
abe3e3094e
|
@ -9,6 +9,7 @@ from zeroconf import (
|
|||
DNSPointer,
|
||||
DNSRecord,
|
||||
InterfaceChoice,
|
||||
IPVersion,
|
||||
NonUniqueNameException,
|
||||
ServiceBrowser,
|
||||
ServiceInfo,
|
||||
|
@ -42,7 +43,9 @@ ZEROCONF_TYPE = "_home-assistant._tcp.local."
|
|||
HOMEKIT_TYPE = "_hap._tcp.local."
|
||||
|
||||
CONF_DEFAULT_INTERFACE = "default_interface"
|
||||
CONF_IPV6 = "ipv6"
|
||||
DEFAULT_DEFAULT_INTERFACE = False
|
||||
DEFAULT_IPV6 = True
|
||||
|
||||
HOMEKIT_PROPERTIES = "properties"
|
||||
HOMEKIT_PAIRED_STATUS_FLAG = "sf"
|
||||
|
@ -54,7 +57,8 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
{
|
||||
vol.Optional(
|
||||
CONF_DEFAULT_INTERFACE, default=DEFAULT_DEFAULT_INTERFACE
|
||||
): cv.boolean
|
||||
): cv.boolean,
|
||||
vol.Optional(CONF_IPV6, default=DEFAULT_IPV6): cv.boolean,
|
||||
}
|
||||
)
|
||||
},
|
||||
|
@ -68,11 +72,17 @@ async def async_get_instance(hass):
|
|||
return await hass.async_add_executor_job(_get_instance, hass)
|
||||
|
||||
|
||||
def _get_instance(hass, default_interface=False):
|
||||
def _get_instance(hass, default_interface=False, ipv6=True):
|
||||
"""Create an instance."""
|
||||
logging.getLogger("zeroconf").setLevel(logging.NOTSET)
|
||||
args = [InterfaceChoice.Default] if default_interface else []
|
||||
zeroconf = HaZeroconf(*args)
|
||||
|
||||
zc_args = {}
|
||||
if default_interface:
|
||||
zc_args["interfaces"] = InterfaceChoice.Default
|
||||
if not ipv6:
|
||||
zc_args["ip_version"] = IPVersion.V4Only
|
||||
|
||||
zeroconf = HaZeroconf(**zc_args)
|
||||
|
||||
def stop_zeroconf(_):
|
||||
"""Stop Zeroconf."""
|
||||
|
@ -115,8 +125,13 @@ class HaZeroconf(Zeroconf):
|
|||
|
||||
def setup(hass, config):
|
||||
"""Set up Zeroconf and make Home Assistant discoverable."""
|
||||
zc_config = config.get(DOMAIN, {})
|
||||
zeroconf = hass.data[DOMAIN] = _get_instance(
|
||||
hass, config.get(DOMAIN, {}).get(CONF_DEFAULT_INTERFACE)
|
||||
hass,
|
||||
default_interface=zc_config.get(
|
||||
CONF_DEFAULT_INTERFACE, DEFAULT_DEFAULT_INTERFACE
|
||||
),
|
||||
ipv6=zc_config.get(CONF_IPV6, DEFAULT_IPV6),
|
||||
)
|
||||
|
||||
# Get instance UUID
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
"""Test Zeroconf component setup process."""
|
||||
import pytest
|
||||
from zeroconf import InterfaceChoice, ServiceInfo, ServiceStateChange
|
||||
from zeroconf import InterfaceChoice, IPVersion, ServiceInfo, ServiceStateChange
|
||||
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.components.zeroconf import CONF_DEFAULT_INTERFACE
|
||||
from homeassistant.components.zeroconf import CONF_DEFAULT_INTERFACE, CONF_IPV6
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.generated import zeroconf as zc_gen
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
@ -114,6 +114,43 @@ async def test_setup_without_default_interface(hass, mock_zeroconf):
|
|||
assert mock_zeroconf.called_with()
|
||||
|
||||
|
||||
async def test_setup_without_ipv6(hass, mock_zeroconf):
|
||||
"""Test without ipv6."""
|
||||
with patch.object(hass.config_entries.flow, "async_init"), patch.object(
|
||||
zeroconf, "HaServiceBrowser", side_effect=service_update_mock
|
||||
):
|
||||
mock_zeroconf.get_service_info.side_effect = get_service_info_mock
|
||||
assert await async_setup_component(
|
||||
hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {CONF_IPV6: False}}
|
||||
)
|
||||
|
||||
assert mock_zeroconf.called_with(ip_version=IPVersion.V4Only)
|
||||
|
||||
|
||||
async def test_setup_with_ipv6(hass, mock_zeroconf):
|
||||
"""Test without ipv6."""
|
||||
with patch.object(hass.config_entries.flow, "async_init"), patch.object(
|
||||
zeroconf, "HaServiceBrowser", side_effect=service_update_mock
|
||||
):
|
||||
mock_zeroconf.get_service_info.side_effect = get_service_info_mock
|
||||
assert await async_setup_component(
|
||||
hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {CONF_IPV6: True}}
|
||||
)
|
||||
|
||||
assert mock_zeroconf.called_with()
|
||||
|
||||
|
||||
async def test_setup_with_ipv6_default(hass, mock_zeroconf):
|
||||
"""Test without ipv6 as default."""
|
||||
with patch.object(hass.config_entries.flow, "async_init"), patch.object(
|
||||
zeroconf, "HaServiceBrowser", side_effect=service_update_mock
|
||||
):
|
||||
mock_zeroconf.get_service_info.side_effect = get_service_info_mock
|
||||
assert await async_setup_component(hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {}})
|
||||
|
||||
assert mock_zeroconf.called_with()
|
||||
|
||||
|
||||
async def test_homekit_match_partial_space(hass, mock_zeroconf):
|
||||
"""Test configured options for a device are loaded via config entry."""
|
||||
with patch.dict(
|
||||
|
|
Loading…
Reference in New Issue