Python · 1750 bytes Raw Blame History
1 """SSH/SFTP connection management for wulFTP."""
2
3 import os
4 from dataclasses import dataclass
5 from pathlib import Path
6 from typing import Dict, Optional
7
8 import paramiko
9 from paramiko import SSHConfig
10 from dotenv import load_dotenv
11
12 # Load environment variables
13 load_dotenv()
14
15
16 @dataclass
17 class SSHHost:
18 """Represents an SSH host configuration."""
19 alias: str
20 hostname: str
21 port: int = 22
22 user: Optional[str] = None
23 key_file: Optional[str] = None
24
25 def display_name(self) -> str:
26 """Get display name for UI."""
27 if self.user:
28 return f"{self.alias} ({self.user}@{self.hostname})"
29 return f"{self.alias} ({self.hostname})"
30
31
32 def load_ssh_config() -> Dict[str, SSHHost]:
33 """Load SSH hosts from ~/.ssh/config and environment."""
34 hosts = {}
35 config_path = Path.home() / ".ssh" / "config"
36
37 if config_path.exists():
38 config = SSHConfig()
39 with open(config_path) as f:
40 config.parse(f)
41
42 for host in config.get_hostnames():
43 if host == "*":
44 continue
45
46 cfg = config.lookup(host)
47 hosts[host] = SSHHost(
48 alias=host,
49 hostname=cfg.get("hostname", host),
50 port=int(cfg.get("port", 22)),
51 user=cfg.get("user"),
52 key_file=cfg.get("identityfile", [None])[0],
53 )
54
55 # Add custom hosts from environment
56 if os.getenv("WULFTP_HOST"):
57 hosts["env_default"] = SSHHost(
58 alias="Default",
59 hostname=os.getenv("WULFTP_HOST"),
60 port=int(os.getenv("WULFTP_PORT", "22")),
61 user=os.getenv("WULFTP_USER"),
62 key_file=os.getenv("WULFTP_KEY"),
63 )
64
65 return hosts