Ejemplo n.º 1
0
def verify_ipaddress(address: Optional[HostAddress]) -> None:
    if not address:
        raise MKIPAddressLookupError("Host has no IP address configured.")

    if address in ["0.0.0.0", "::"]:
        raise MKIPAddressLookupError(
            "Failed to lookup IP address and no explicit IP address configured")
Ejemplo n.º 2
0
def cached_dns_lookup(
    hostname: HostName,
    *,
    family: socket.AddressFamily,
    is_no_ip_host: bool,
) -> Optional[str]:
    cache = _config_cache.get("cached_dns_lookup")

    cache_id = hostname, family

    # Address has already been resolved in prior call to this function?
    try:
        return cache[cache_id]
    except KeyError:
        pass

    ip_lookup_cache = _get_ip_lookup_cache()

    cached_ip = ip_lookup_cache.get(cache_id)
    if cached_ip and config.use_dns_cache:
        cache[cache_id] = cached_ip
        return cached_ip

    if is_no_ip_host:
        cache[cache_id] = None
        return None

    # Now do the actual DNS lookup
    try:
        ipa = socket.getaddrinfo(hostname, None, family)[0][4][0]

        # Update our cached address if that has changed or was missing
        if ipa != cached_ip:
            console.verbose("Updating %s DNS cache for %s: %s\n" % (family, hostname, ipa))
            ip_lookup_cache.update_cache(cache_id, ipa)

        cache[cache_id] = ipa  # Update in-memory-cache
        return ipa

    except (MKTerminate, MKTimeout):
        # We should be more specific with the exception handler below, then we
        # could drop this special handling here
        raise

    except Exception as e:
        # DNS failed. Use cached IP address if present, even if caching
        # is disabled.
        if cached_ip:
            cache[cache_id] = cached_ip
            return cached_ip
        cache[cache_id] = None
        raise MKIPAddressLookupError("Failed to lookup %s address of %s via DNS: %s" % (
            {
                socket.AF_INET: "IPv4",
                socket.AF_INET6: "IPv6"
            }[family],
            hostname,
            e,
        ))
Ejemplo n.º 3
0
def _actual_dns_lookup(
    *,
    host_name: HostName,
    family: socket.AddressFamily,
    fallback: Optional[HostAddress] = None,
) -> HostAddress:
    try:
        return socket.getaddrinfo(host_name, None, family)[0][4][0]
    except (MKTerminate, MKTimeout):
        # We should be more specific with the exception handler below, then we
        # could drop this special handling here
        raise
    except Exception as e:
        if fallback:
            return fallback
        family_str = {socket.AF_INET: "IPv4", socket.AF_INET6: "IPv6"}[family]
        raise MKIPAddressLookupError(
            f"Failed to lookup {family_str} address of {host_name} via DNS: {e}"
        )
Ejemplo n.º 4
0
 def fake_lookup_ip_address(host_config, family=None, for_mgmt_board=True):
     raise MKIPAddressLookupError("Failed to ...")
Ejemplo n.º 5
0
 def fake_lookup_ip_address(*_a, **_kw):
     raise MKIPAddressLookupError("Failed to ...")
Ejemplo n.º 6
0
def cached_dns_lookup(
    hostname: HostName,
    *,
    family: socket.AddressFamily,
    force_file_cache_renewal: bool,
) -> Optional[str]:
    """Cached DNS lookup in *two* caching layers

    1) outer layer:
       A *config cache* that caches all calls until the configuration is changed or runtime ends.
       Other than activating a changed configuration there is no way to remove cached results during
       runtime. Changes made by a differend process will not be noticed.
       This layer caches `None` for lookups that failed, after raising the corresponding exception
       *once*. Subsequent lookups for this hostname / family combination  will not raise an
       exception, until the configuration is changed.

    2) inner layer:
       This layer caches *successful* lookups of host name / IP address
       family combinations, and writes them to a file.
       Note that after the file is loaded initially, the data in the IPLookupCache is keept in sync
       with the file, and itself stored in a dict in the config cache.
       Before a new value is writte to file, the file is re-read, as another process might have
       changed it.
    """
    cache = _config_cache.get("cached_dns_lookup")
    cache_id = hostname, family

    # Address has already been resolved in prior call to this function?
    try:
        return cache[cache_id]
    except KeyError:
        pass

    ip_lookup_cache = _get_ip_lookup_cache()

    cached_ip = ip_lookup_cache.get(cache_id)
    if cached_ip and not force_file_cache_renewal:
        cache[cache_id] = cached_ip
        return cached_ip

    # Now do the actual DNS lookup
    try:
        ipa = socket.getaddrinfo(hostname, None, family)[0][4][0]

        # Update our cached address if that has changed or was missing
        if ipa != cached_ip:
            console.verbose("Updating %s DNS cache for %s: %s\n" %
                            (family, hostname, ipa))
            ip_lookup_cache.update_cache(cache_id, ipa)

        cache[cache_id] = ipa  # Update in-memory-cache
        return ipa

    except (MKTerminate, MKTimeout):
        # We should be more specific with the exception handler below, then we
        # could drop this special handling here
        raise

    except Exception as e:
        # DNS failed. Use cached IP address if present, even if caching
        # is disabled.
        if cached_ip:
            cache[cache_id] = cached_ip
            return cached_ip
        cache[cache_id] = None
        raise MKIPAddressLookupError(
            "Failed to lookup %s address of %s via DNS: %s" % (
                {
                    socket.AF_INET: "IPv4",
                    socket.AF_INET6: "IPv6"
                }[family],
                hostname,
                e,
            ))