import re import os.path from pathlib import Path from typing import Optional # load utility functions def load_sshconfig_server_list(sshconfig: Path, hostfilter: Optional[re.Pattern] = None, lineSkip: Optional[re.Pattern] = None) -> set: """ Load a list of servers from an ssh configuration file. """ output = set() with sshconfig.open() as inconfig: for line in [l.strip() for l in inconfig]: if line.startswith("Host "): if lineSkip and lineSkip.match(line): continue hostinfo = line.split('#', 2)[0] hostname = hostinfo.split()[-1] if hostfilter and not hostfilter.match(hostname): continue output.add(hostname) return output def load_bare_server_list(serverlist: Path, hostfilter: Optional[re.Pattern] = None, lineSkip: Optional[re.Pattern] = None) -> set: """ Load a list of servers from a simple text file. """ output = set() with sshconfig.open() as inconfig: for line in [l.strip() for l in inconfig]: if not line: continue if lineSkip and lineSkip.match(line): continue hostinfo = line.split('#', 2)[0] hostname = hostinfo.split()[-1] if hostfilter and not hostfilter.match(hostname): continue output.add(hostname) return output def load_config(config_path: Path): output = dict() with config_path.open() as inconfig: section = 'global' cmd = False lineno = 0 for rline in inconfig: lineno += 1 line = rline.strip() if not line: continue if line.startswith('#'): continue if line.startswith('['): section = line[1:-1] if section.startswith("cmd") or section == 'startup': cmd = True output.setdefault(section, list()) else: cmd = False output.setdefault(section, dict()) continue if cmd: output[section].append(line) else: if not '=' in line: print(f"config parse error, line {lineno}: {line}") continue kv = line.split('=', 2) if len(kv) == 1: value = '' else: value = kv[1] output[section][kv[0]] = value return output