import os import asyncio from collections import OrderedDict from .utils import print_error, print_warning, print_info, safe_input from .list_hosts import list_hosts, load_config_file, check_ssh_port async def get_all_host_blocks(conf_dir): """ Similar to list_hosts, but returns the list of host blocks + a table of results. We'll build a table ourselves so we can map row numbers to actual host labels. """ import glob import socket pattern = os.path.join(conf_dir, "*", "config") conf_files = sorted(glob.glob(pattern)) all_blocks = [] for conf_file in conf_files: blocks = load_config_file(conf_file) all_blocks.extend(blocks) # If no blocks found, return empty if not all_blocks: return [] # We want to do a partial version of check_host to get row data # so we can display the table right here and keep track of each block’s host label. # But let's do it similarly to list_hosts: table_rows = [] for idx, b in enumerate(all_blocks, start=1): host_label = b.get("Host", "N/A") hostname = b.get("HostName", "N/A") user = b.get("User", "N/A") port = int(b.get("Port", "22")) identity_file = b.get("IdentityFile", "N/A") # Identity check if identity_file != "N/A": expanded_identity = os.path.expanduser(identity_file) identity_exists = os.path.isfile(expanded_identity) else: identity_exists = False # IP resolution try: ip_address = socket.gethostbyname(hostname) except socket.error: ip_address = None # Port check if ip_address: port_open = await asyncio.wait_for(check_ssh_port(ip_address, port), timeout=1) else: port_open = False # Colors for display (optional, or we can keep it simple): ip_display = f"\033[0;32m{ip_address}\033[0m" if ip_address else "\033[0;31mN/A\033[0m" port_display = f"\033[0;32m{port}\033[0m" if port_open else f"\033[0;31m{port}\033[0m" identity_disp= f"\033[0;32m{identity_file}\033[0m" if identity_exists else f"\033[0;31m{identity_file}\033[0m" row = [ idx, host_label, user, port_display, hostname, ip_display, identity_disp ] table_rows.append(row) # Print the table from tabulate import tabulate headers = ["No.", "Host", "User", "Port", "HostName", "IP Address", "IdentityFile"] print("\nSSH Conf Subdirectory Host List") print(tabulate(table_rows, headers=headers, tablefmt="grid")) return all_blocks def edit_host(conf_dir): """ Let the user update fields for an existing host in ~/.ssh/conf/