diff --git a/scripts/deploy/misc.py b/scripts/deploy/misc.py index 1993c5b2e..156d5ba62 100644 --- a/scripts/deploy/misc.py +++ b/scripts/deploy/misc.py @@ -120,92 +120,76 @@ def get_known_targets() -> dict[str, dict[str, str]]: return KNOWN_TARGETS -class Target: - def __init__(self, identifier: str) -> None: - """ - Target represents a robot to deploy to. - It can be initialized with a hostname, IP address or a robot name. - """ - self.ip: Optional[ipaddress.IPv4Address | ipaddress.IPv6Address] = self._identify_ip(identifier) - self.hostname: Optional[str] = None # TODO: Get the hostname after we have a connection - - def _identify_ip(self, identifier: str) -> Optional[ipaddress.IPv4Address | ipaddress.IPv6Address]: - """ - Identifies an IP address from an identifier. - The identifier can be a hostname, IP address or a robot name. - - :param identifier: The identifier to identify the target from. - :return: IP address of the identified target. - """ - print_debug(f"Identifying IP address from identifier: '{identifier}'.") - - # Is the identifier an IP address? - try: - print_debug(f"Checking if {identifier} is a IP address") - ip = ipaddress.ip_address(identifier) - print_debug(f"Found {ip} as IP address") - return ip - except ValueError: - print_debug("Entered target is not a IP-address.") - - # It was not an IP address, so we try to find a known target - for ip, values in KNOWN_TARGETS.items(): - # Is the identifier a known hostname? - known_hostname = values.get("hostname", None) - if known_hostname: - print_debug(f"Comparing {identifier} with {known_hostname}") - if known_hostname.strip() == identifier.strip(): - print_debug(f"Found hostname '{known_hostname}' for identifier '{identifier}'. Using its IP {ip}.") - return ipaddress.ip_address(ip) - else: - print_debug(f"Hostname '{known_hostname}' does not match identifier '{identifier}'.") - - # Is the identifier a known robot name? - known_robot_name = values.get("robot_name", None) - if known_robot_name: - print_debug(f"Comparing '{identifier}' with '{known_robot_name}'.") - if known_robot_name.strip() == identifier.strip(): - print_debug( - f"Found robot name '{known_robot_name}' for identifier '{identifier}'. Using its IP {ip}." - ) - return ipaddress.ip_address(ip) - else: - print_debug(f"Robot name '{known_robot_name}' does not match identifier '{identifier}'.") - - def __str__(self) -> str: - """Returns the target's hostname if available or IP address.""" - return self.hostname if self.hostname is not None else str(self.ip) - - def get_connection_identifier(self) -> str: - """Returns the target's IP address.""" - return str(self.ip) - - -def _parse_targets(input_targets: str) -> list[Target]: +def _identify_ip(identifier: str) -> str | None: + """ + Identifies an IP address from an identifier. + The identifier can be a hostname, IP address or a robot name. + + :param identifier: The identifier to identify the target from. + :return: IP address of the identified target. + """ + print_debug(f"Identifying IP address from identifier: '{identifier}'.") + + # Is the identifier an IP address? + try: + print_debug(f"Checking if {identifier} is an IP address") + ip = ipaddress.ip_address(identifier) + print_debug(f"Identified {ip} as an IP address") + return str(ip) + except ValueError: + print_debug("Entered target is not an IP-address.") + + # It was not an IP address, so we try to find a known target + for ip, values in KNOWN_TARGETS.items(): + # Is the identifier a known hostname? + known_hostname = values.get("hostname", None) + if known_hostname: + print_debug(f"Comparing {identifier} with {known_hostname}") + if known_hostname.strip() == identifier.strip(): + print_debug(f"Identified hostname '{known_hostname}' for '{identifier}'. Using its IP {ip}.") + return str(ipaddress.ip_address(ip)) + else: + print_debug(f"Hostname '{known_hostname}' does not match identifier '{identifier}'.") + + # Is the identifier a known robot name? + known_robot_name = values.get("robot_name", None) + if known_robot_name: + print_debug(f"Comparing '{identifier}' with '{known_robot_name}'.") + if known_robot_name.strip() == identifier.strip(): + print_debug(f"Identified robot name '{known_robot_name}' for '{identifier}'. Using its IP {ip}.") + return str(ipaddress.ip_address(ip)) + else: + print_debug(f"Robot name '{known_robot_name}' does not match '{identifier}'.") + + +def _parse_targets(input_targets: str) -> list[str]: """ - Parse target input into usable Targets. + Parse target input into usable target IP addresses. :param input_targets: The input string of targets as a comma separated string of either hostnames, robot names or IPs. - :return: List of Targets + :return: List of target IP addresses. """ - targets: list[Target] = [] + target_ips: list[str] = [] for input_target in input_targets.split(","): try: - target = Target(input_target) + target_ip = _identify_ip(input_target) except ValueError: - print_err(f"Could not determine hostname or IP from input: '{input_target}'") + print_err(f"Could not determine IP address from input: '{input_target}'") + exit(1) + if target_ip is None: + print_err(f"Could not determine IP address from input:' {input_target}'") exit(1) - targets.append(target) - return targets + target_ips.append(target_ip) + return target_ips def _get_connections_from_targets( - targets: list[Target], user: str, connection_timeout: Optional[int] = 10 + target_ips: list[str], user: str, connection_timeout: Optional[int] = 10 ) -> ThreadingGroup: """ - Get connections to the given Targets using the given username. + Get connections to the given target IP addresses using the given username. - :param targets: The Targets to connect to + :param target_ips: The target IP addresses to connect to :param user: The username to connect with :param connection_timeout: Timeout for establishing the connection :return: The connections @@ -219,14 +203,17 @@ def _concat_exception_args(e: Exception) -> str: reason += f"{arg} " return reason - hosts: list[str] = [target.get_connection_identifier() for target in targets] - connections = ThreadingGroup(*hosts, user=user, connect_timeout=connection_timeout) + connections = ThreadingGroup(*target_ips, user=user, connect_timeout=connection_timeout) failures: list[tuple[Connection, str]] = [] # List of tuples of failed connections and their error message for connection in connections: try: print_debug(f"Connecting to {connection.host}...") connection.open() print_debug(f"Connected to {connection.host}...") + print_debug(f"Getting hostname of {connection.host}...") + hostname: str = connection.run("hostname", hide=hide_output()).stdout.strip() + print_debug(f"Got hostname of {connection.host}: {hostname}. Setting is as original hostname.") + connection.original_host = hostname except AuthenticationException as e: failures.append( ( @@ -257,11 +244,13 @@ def _get_connections_from_all_known_targets(user: str, connection_timeout: Optio :param connection_timeout: Timeout for establishing the connection :return: The connections """ - # Get hosts from all known targets - hosts: list[str] = [Target(hostname).get_connection_identifier() for hostname in KNOWN_TARGETS.keys()] + # Get all known target IP addresses + target_ips: list[str] = list(KNOWN_TARGETS.keys()) # Create connections - connections: list[Connection] = [Connection(host, user=user, connect_timeout=connection_timeout) for host in hosts] + connections: list[Connection] = [ + Connection(host, user=user, connect_timeout=connection_timeout) for host in target_ips + ] # Connect to all hosts open_connections: list[Connection] = [] @@ -293,11 +282,11 @@ def get_connections_from_targets( :return: The connections to the targets """ if input_targets == "ALL": - print_info(f"Connecting to all known Targets: {KNOWN_TARGETS.keys()}") + print_info(f"Connecting to all known targets: {KNOWN_TARGETS.keys()}") return _get_connections_from_all_known_targets(user=user, connection_timeout=connection_timeout) return _get_connections_from_targets( - targets=_parse_targets(input_targets), user=user, connection_timeout=connection_timeout + target_ips=_parse_targets(input_targets), user=user, connection_timeout=connection_timeout ) diff --git a/scripts/deploy/tasks/abstract_task.py b/scripts/deploy/tasks/abstract_task.py index 5aefcd3bd..8e584c1ec 100644 --- a/scripts/deploy/tasks/abstract_task.py +++ b/scripts/deploy/tasks/abstract_task.py @@ -43,7 +43,7 @@ def _results_hosts(self, results) -> list[str]: :param results: The results of the task. :return: The list of hosts that have results. """ - return [connection.host for connection in results.keys()] + return [connection.original_host for connection in results.keys()] def _succeeded_hosts(self, results: GroupResult) -> list[str]: """