diff --git a/app/app.py b/app/app.py index 4bd09ce..1c2910e 100644 --- a/app/app.py +++ b/app/app.py @@ -51,49 +51,51 @@ class Server(db.Model): def parse_infrastructure_conf(): servers = [] current_group = None - current_host = None # track the last top-level host for nesting + current_host = None # track the last host for nesting try: with open(INFRA_CONF_PATH) as f: for line in f: line = line.rstrip('\n') - if not line.strip() or line.strip().startswith('#'): + stripped = line.strip() + if not stripped or stripped.startswith('#'): continue + # Group header: no leading whitespace if line[0] not in (' ', '\t'): - current_group = line.strip() + current_group = stripped current_host = None + continue + # Detect prefix: -- child VM, - host + if stripped.startswith('--'): + is_child = True + rest = stripped[2:].strip() + elif stripped.startswith('-'): + is_child = False + rest = stripped[1:].strip() else: - # Detect indent level: double indent = child VM - # Normalize: count leading whitespace treating tab as 4 spaces - raw_indent = 0 - for ch in line: - if ch == '\t': - raw_indent += 4 - elif ch == ' ': - raw_indent += 1 - else: - break - is_child = raw_indent >= 8 + # Legacy: no dash prefix, treat as host + is_child = False + rest = stripped - parts = line.strip().split(None, 1) - entry = parts[0] if parts else '' - url = parts[1] if len(parts) > 1 else '' - if '@' in entry: - user, host = entry.split('@', 1) + parts = rest.split(None, 1) + entry = parts[0] if parts else '' + url = parts[1] if len(parts) > 1 else '' + if '@' in entry: + user, host = entry.split('@', 1) + else: + user, host = 'infmap', entry + if host: + parent = '' + if is_child and current_host: + parent = current_host else: - user, host = 'infmap', entry - if host: - parent = '' - if is_child and current_host: - parent = current_host - else: - current_host = host.strip() - servers.append({ - 'group': current_group or 'Default', - 'username': user.strip(), - 'hostname': host.strip(), - 'url': url.strip(), - 'parent_hostname': parent, - }) + current_host = host.strip() + servers.append({ + 'group': current_group or 'Default', + 'username': user.strip(), + 'hostname': host.strip(), + 'url': url.strip(), + 'parent_hostname': parent, + }) except FileNotFoundError: logger.error("infrastructure.conf not found at %s", INFRA_CONF_PATH) return servers @@ -284,7 +286,15 @@ def index(): for hostname in children_map: children_map[hostname].sort(key=lambda s: _ip_sort_key(s.primary_ip)) - # Group parents + # Get group order from config file + config_entries = parse_infrastructure_conf() + group_order = [] + for e in config_entries: + g = e['group'] + if g not in group_order: + group_order.append(g) + + # Group parents, preserving config order groups = {} for s in parents: g = s.group_name or 'Default' @@ -292,6 +302,16 @@ def index(): groups[g] = [] groups[g].append(s) + # Re-order groups to match config + ordered_groups = {} + for g in group_order: + if g in groups: + ordered_groups[g] = groups.pop(g) + # Append any remaining groups not in config + for g in groups: + ordered_groups[g] = groups[g] + groups = ordered_groups + # Sort servers within each group by IP (numerically) for g in groups: groups[g].sort(key=lambda s: _ip_sort_key(s.primary_ip))