mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 23:41:48 -05:00
Fix stack devices merging with container devices in Portainer (#164135)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
This commit is contained in:
@@ -91,7 +91,7 @@ class PortainerContainerEntity(PortainerCoordinatorEntity):
|
||||
# else it's the endpoint
|
||||
via_device=(
|
||||
DOMAIN,
|
||||
f"{coordinator.config_entry.entry_id}_{self.endpoint_id}_{device_info.stack.name}"
|
||||
f"{coordinator.config_entry.entry_id}_{self.endpoint_id}_stack_{device_info.stack.id}"
|
||||
if device_info.stack
|
||||
else f"{coordinator.config_entry.entry_id}_{self.endpoint_id}",
|
||||
),
|
||||
@@ -135,7 +135,7 @@ class PortainerStackEntity(PortainerCoordinatorEntity):
|
||||
identifiers={
|
||||
(
|
||||
DOMAIN,
|
||||
f"{coordinator.config_entry.entry_id}_{self.endpoint_id}_{self.device_name}",
|
||||
f"{coordinator.config_entry.entry_id}_{self.endpoint_id}_stack_{self.stack_id}",
|
||||
)
|
||||
},
|
||||
manufacturer=DEFAULT_NAME,
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
# serializer version: 1
|
||||
# name: test_device_registry
|
||||
list([
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/dashboard',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Endpoint',
|
||||
'model_id': None,
|
||||
'name': 'my-environment',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/aa86eacfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_funny_chatelet',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'funny_chatelet',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/dd19facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_focused_einstein',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'focused_einstein',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/ee20facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_practical_morse',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'practical_morse',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/stacks/webstack',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_stack_1',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Stack',
|
||||
'model_id': None,
|
||||
'name': 'webstack',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/bb97facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_serene_banach',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'serene_banach',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/cc08facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_stoic_turing',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'stoic_turing',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
@@ -8,6 +8,7 @@ from pyportainer.exceptions import (
|
||||
PortainerTimeoutError,
|
||||
)
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.portainer.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
@@ -166,3 +167,19 @@ async def test_migration_v3_to_v4(
|
||||
(DOMAIN, f"{entry.entry_id}_1_adguard"),
|
||||
}
|
||||
assert entity_after.unique_id == f"{entry.entry_id}_1_adguard_container"
|
||||
|
||||
|
||||
async def test_device_registry(
|
||||
hass: HomeAssistant,
|
||||
mock_portainer_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test devices are correctly registered."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
device_entries = dr.async_entries_for_config_entry(
|
||||
device_registry, mock_config_entry.entry_id
|
||||
)
|
||||
assert device_entries == snapshot
|
||||
|
||||
Reference in New Issue
Block a user