Source code for deode.host_actions

#!/usr/bin/env python3
"""Handle host detection."""

import os
import re
import socket

import yaml

from .config_parser import ConfigPaths, GeneralConstants
from .logs import logger


[docs] class DeodeHost: """DeodeHost object.""" def __init__(self, known_hosts=None, known_hosts_file=None): """Constructs the DeodeHost object.""" self.known_hosts = self._load_known_hosts( known_hosts=known_hosts, known_hosts_file=known_hosts_file ) self.available_hosts = list(self.known_hosts) self.default_host = self.available_hosts[0] self.deode_host = os.getenv("DEODE_HOST") self.hostname = socket.gethostname() def _load_known_hosts(self, known_hosts=None, known_hosts_file=None): """Loads the known_hosts config. Args: known_hosts (dict, optional): Known hosts dict. Defaults to None known_hosts_file (str, optional): Known hosts file. Defaults to None Raises: RuntimeError: No host identifiers loaded Returns: known_host (dict): Known hosts config """ if known_hosts is not None: return known_hosts if known_hosts_file is None: known_hosts_file = ConfigPaths.path_from_subpath("known_hosts.yml") with open(known_hosts_file, "rb") as infile: known_hosts = yaml.safe_load(infile) if known_hosts is None: raise RuntimeError(f"No hosts available in {known_hosts_file}") return known_hosts def _detect_by_hostname(self, hostname_pattern): """Detect deode host by hostname regex. Args: hostname_pattern(list|str) : hostname regex to match Returns: (boolean): Match or not """ logger.debug("hostname={}", self.hostname) hh = [hostname_pattern] if isinstance(hostname_pattern, str) else hostname_pattern for x in hh: if re.match(x, self.hostname): logger.debug("Deode-host detected by hostname {}", x) return True return False def _detect_by_env(self, env_variable): """Detect deode host by environment variable regex. Args: env_variable(dict) : Environment variables to search for Returns: (boolean): Match or not """ for var, value in env_variable.items(): if var in os.environ: vv = [value] if isinstance(value, str) else value for x in vv: if re.match(x, os.environ[var]): logger.debug( "Deode-host detected by environment variable {}={}", var, x ) return True return False
[docs] def detect_deode_host(self): """Detect deode host by matching various properties. First check self.deode_host as set by os.getenv("DEODE_HOST"), second use the defined hosts in known_hosts.yml. If no matches are found return the first host defined in known_hosts.yml Raises: RuntimeError: Ambiguous matches Returns: deode_host (str): mapped hostname """ if self.deode_host is not None: return self.deode_host matches = [] for deode_host, detect_methods in self.known_hosts.items(): for method, pattern in detect_methods.items(): fname = f"_detect_by_{method}" if hasattr(self, fname): function = getattr(self, fname) if function(pattern): matches.append(deode_host) break else: raise RuntimeError(f"No deode-host detection using {method}") if len(matches) == 0: matches = list(self.known_hosts)[0:1] logger.info( f"No deode-host detected from {self.hostname}, use {self.default_host}" ) if len(matches) > 1: raise RuntimeError(f"Ambiguous matches: {matches}") return matches[0]
[docs] def set_deode_home(config, deode_home=None): """Set deode_home in various ways. Args: config (.config_parser.ParsedConfig): Parsed config file contents. deode_home (str): Externally set deode_home Returns: deode_home """ if deode_home is None: try: deode_home_from_config = config["platform.deode_home"] except KeyError: deode_home_from_config = "set-by-the-system" if deode_home_from_config != "set-by-the-system": deode_home = deode_home_from_config else: deode_home = str(GeneralConstants.PACKAGE_DIRECTORY) return deode_home