def select_host(hosts, ranking_string=None, blacklist=None, blacklist_name=None): """Select a host from the provided list. If no ranking is provided (in `ranking_string`) then random selection is used. Args: hosts (list): List of host names to choose from. NOTE: Host names must be identifiable from the host where the call is executed. ranking_string (str): A multiline string containing Python expressions to filter hosts by e.g:: # only consider hosts with less than 70% cpu usage # and a server load of less than 5 cpu_percent() < 70 getloadavg()[0] < 5 And or Python statements to rank hosts by e.g:: # rank by used cpu, then by load average as a tie-break # (lower scores are better) cpu_percent() getloadavg() Comments are allowed using `#` but not inline comments. blacklist (list): List of host names to filter out. Can be short host names (do not have to be fqdn values) blacklist_name (str): The reason for blacklisting these hosts (used for exceptions). Raises: HostSelectException: In the event that no hosts are available / meet the specified criterion. socket.gaierror: This may be raised in the event of unknown host names for some installations or not for others. Returns: tuple - (hostname, fqdn) the chosen host hostname (str): The hostname as provided to this function. fqdn (str): The fully qualified domain name of this host. """ # standardise host names - remove duplicate items hostname_map = { # note dictionary keys filter out duplicates get_fqdn_by_host(host): host for host in hosts } hosts = list(hostname_map) if blacklist: blacklist = list(set(map(get_fqdn_by_host, blacklist))) # dict of conditions and whether they have been met (for error reporting) data = {host: {} for host in hosts} # filter out `filter_hosts` if provided if blacklist: hosts, data = _filter_by_hostname(hosts, blacklist, blacklist_name, data=data) if not hosts: # no hosts provided / left after filtering raise HostSelectException(data) rankings = [] if ranking_string: # parse rankings rankings = list(_get_rankings(ranking_string)) if not rankings: # no metrics or ranking required, pick host at random hosts = [random.choice(list(hosts))] # nosec if not rankings and len(hosts) == 1: return hostname_map[hosts[0]], hosts[0] # filter and sort by rankings metrics = list({x for x, _ in rankings}) # required metrics results, data = _get_metrics( # get data from each host hosts, metrics, data) hosts = list(results) # some hosts might not be contactable # stop here if we don't need to proceed if not hosts: # no hosts provided / left after filtering raise HostSelectException(data) if not rankings and len(hosts) == 1: return hostname_map[hosts[0]], hosts[0] hosts, data = _filter_by_ranking( # filter by rankings, sort by ranking hosts, rankings, results, data=data) if not hosts: # no hosts provided / left after filtering raise HostSelectException(data) return hostname_map[hosts[0]], hosts[0]
def select_suite_host(**_): raise HostSelectException({})
def select_workflow_host(**_): raise HostSelectException({})