Files

79 lines
2.4 KiB
Python

from collections.abc import Iterable
from .adapters import (
DNS_RECORDS,
PROXY_HOSTS,
NormalizedObject,
Observation,
)
from .normalizer import normalize_hostname, normalize_ipv4
def project_proxy_hosts_to_dns(
observations: Iterable[Observation],
target_ip: str,
*,
include_disabled: bool = False,
) -> list[Observation]:
dns_target = normalize_ipv4(target_ip, "DNS target IP")
projected: list[Observation] = []
for observation in observations:
proxy_host = observation.object
if proxy_host.object_type != PROXY_HOSTS:
continue
if proxy_host.local_key is None:
raise RuntimeError(
"Proxy-host observations require an endpoint-local key"
)
enabled = proxy_host.payload.get("enabled")
if not isinstance(enabled, bool):
raise RuntimeError(
f"Proxy host {proxy_host.local_key} has invalid "
"normalized enabled state"
)
if not enabled and not include_disabled:
continue
domain_names = proxy_host.payload.get("domain_names")
if not isinstance(domain_names, (list, tuple)):
raise RuntimeError(
f"Proxy host {proxy_host.local_key} has invalid "
"normalized domain_names"
)
for raw_domain in domain_names:
hostname, wildcard = normalize_hostname(
str(raw_domain),
allow_wildcard=True,
)
projected.append(
Observation(
endpoint_id=observation.endpoint_id,
object=NormalizedObject(
object_type=DNS_RECORDS,
logical_key=hostname,
local_key=(
f"{proxy_host.local_key}:{hostname}"
),
payload={
"hostname": hostname,
"ip": dns_target,
"record_type": "A",
"wildcard": wildcard,
},
),
observed_at=observation.observed_at,
)
)
return sorted(
projected,
key=lambda item: (
item.endpoint_id,
item.object.logical_key,
item.object.local_key or "",
),
)