1
0
Fork 1
mirror of https://github.com/thatmattlove/hyperglass.git synced 2026-01-17 08:48:05 +00:00

Fix field validation for device config.

Some of the field validator methods for device config used `values` as a dictionary (presumably from an old version of pydantic). This is now passed as a `ValidationInfo` object by pydantic, which caused issues when code attempted to access it. The affected methods have been updated to fix the issue.

Fix #311

Signed-off-by: Mattie Nickson <mnickson@sidingsmedia.com>
This commit is contained in:
Mattie Nickson 2025-06-04 13:33:28 +01:00
parent 15491f904b
commit d653461b5d
No known key found for this signature in database

View file

@ -170,7 +170,7 @@ class Device(HyperglassModelWithId, extra="allow"):
@field_validator("address") @field_validator("address")
def validate_address( def validate_address(
cls, value: t.Union[IPv4Address, IPv6Address, str], values: t.Dict[str, t.Any] cls, value: t.Union[IPv4Address, IPv6Address, str], info: ValidationInfo
) -> t.Union[IPv4Address, IPv6Address, str]: ) -> t.Union[IPv4Address, IPv6Address, str]:
"""Ensure a hostname is resolvable.""" """Ensure a hostname is resolvable."""
@ -178,14 +178,14 @@ class Device(HyperglassModelWithId, extra="allow"):
if not any(resolve_hostname(value)): if not any(resolve_hostname(value)):
raise ConfigError( raise ConfigError(
"Device '{d}' has an address of '{a}', which is not resolvable.", "Device '{d}' has an address of '{a}', which is not resolvable.",
d=values["name"], d=info.data["name"],
a=value, a=value,
) )
return value return value
@field_validator("avatar") @field_validator("avatar")
def validate_avatar( def validate_avatar(
cls, value: t.Union[FilePath, None], values: t.Dict[str, t.Any] cls, value: t.Union[FilePath, None], info: ValidationInfo
) -> t.Union[FilePath, None]: ) -> t.Union[FilePath, None]:
"""Migrate avatar to static directory.""" """Migrate avatar to static directory."""
if value is not None: if value is not None:
@ -198,7 +198,7 @@ class Device(HyperglassModelWithId, extra="allow"):
target = Settings.static_path / "images" / value.name target = Settings.static_path / "images" / value.name
copied = shutil.copy2(value, target) copied = shutil.copy2(value, target)
log.bind( log.bind(
device=values["name"], device=info.data["name"],
source=str(value), source=str(value),
destination=str(target), destination=str(target),
).debug("Copied device avatar") ).debug("Copied device avatar")
@ -210,24 +210,24 @@ class Device(HyperglassModelWithId, extra="allow"):
return value return value
@field_validator("platform", mode="before") @field_validator("platform", mode="before")
def validate_platform(cls: "Device", value: t.Any, values: t.Dict[str, t.Any]) -> str: def validate_platform(cls: "Device", value: t.Any, info: ValidationInfo) -> str:
"""Validate & rewrite device platform, set default `directives`.""" """Validate & rewrite device platform, set default `directives`."""
if value == "http": if value == "http":
if values.get("http") is None: if info.data.get("http") is None:
raise ConfigError( raise ConfigError(
"Device '{device}' has platform 'http' configured, but no http parameters are defined.", "Device '{device}' has platform 'http' configured, but no http parameters are defined.",
device=values["name"], device=info.data["name"],
) )
if value is None: if value is None:
if values.get("http") is not None: if info.data.get("http") is not None:
value = "http" value = "http"
else: else:
# Ensure device platform is defined. # Ensure device platform is defined.
raise ConfigError( raise ConfigError(
"Device '{device}' is missing a 'platform' (Network Operating System) property", "Device '{device}' is missing a 'platform' (Network Operating System) property",
device=values["name"], device=info.data["name"],
) )
if value in SCRAPE_HELPERS.keys(): if value in SCRAPE_HELPERS.keys():