test: add a local Docker test environment for all features
testenv/ starts two real NetBox 4.7 instances (v2 and v1 token), SSH targets on public, mgmt, and prod networks, a jump host, an IPv6-only host, a static host, and a client with ssh, sftp, scp, tmux, zellij, bash, zsh, and fish. A seed script fills NetBox through the REST API. 141 end-to-end checks cover cache and refresh filters, connecting, all resolver strategies, multiple instances, shortcuts and rewrites, SSH options and rules, static hosts, sftp/scp incl. IPv6 and jump hosts, tunnels, local notes and NetBox comments, completion and shell hooks, the TUI (driven through tmux), the configurator, and uninstall. Local only: testenv/up.sh, test.sh, shell.sh, down.sh. Not part of CI/CD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
55e7a5106b
commit
dbb99bdded
34 files changed
+1215
No files matched your search
@@ -0,0 +1,63 @@
|
||||
# Every resolver strategy against real NetBox data. cache.ttl 0 makes every
|
||||
# connection ask NetBox, so each config change takes effect immediately.
|
||||
jump=' - match: {instance: fsn}
|
||||
proxy_jump: ops@10.231.0.30
|
||||
- match: {name: "bastion*"}
|
||||
proxy_jump: none'
|
||||
|
||||
config <<EOF
|
||||
cache: {ttl: 0}
|
||||
resolver: {strategies: [primary_ip]}
|
||||
ssh:
|
||||
default_user: ops
|
||||
rules:
|
||||
$jump
|
||||
EOF
|
||||
expect_eq "primary_ip uses prod address via bastion" "ssh -l ops -J ops@10.231.0.30 10.231.2.11" netssh --dry-run fsn/fsn1-pve1.hoster.test
|
||||
expect_eq "primary_ip connects through the jump host" "fsn1-pve1" netssh fsn/fsn1-pve1.hoster.test hostname
|
||||
expect_eq "bastion rule disables the jump" "ssh -l ops 10.231.0.30" netssh --dry-run fsn/bastion.hoster.test
|
||||
expect_eq "IPv6 primary address" "ssh -l ops -J ops@10.231.0.30 fd00:30::60" netssh --dry-run fsn/v6-host
|
||||
|
||||
config <<'EOF'
|
||||
cache: {ttl: 0}
|
||||
resolver:
|
||||
strategies: [management_subnet, primary_ip]
|
||||
management_subnets: [10.231.1.0/24]
|
||||
ssh: {default_user: ops}
|
||||
EOF
|
||||
expect_eq "management_subnet" "ssh -l ops 10.231.1.12" netssh --dry-run fsn/fsn1-pve2.hoster.test
|
||||
expect_eq "management_subnet falls back to primary_ip" "ssh -l ops 10.231.2.21" netssh --dry-run fsn/web1
|
||||
|
||||
config <<'EOF'
|
||||
cache: {ttl: 0}
|
||||
resolver:
|
||||
strategies: [interface_name, primary_ip]
|
||||
interface_name: mgmt0
|
||||
ssh: {default_user: ops}
|
||||
EOF
|
||||
expect_eq "interface_name" "ssh -l ops 10.231.1.13" netssh --dry-run fsn/fsn1-pve3.hoster.test
|
||||
expect_eq "interface_name connects" "fsn1-pve3" netssh fsn/fsn1-pve3.hoster.test hostname
|
||||
expect_eq "interface_name falls back for VMs" "ssh -l ops 10.231.2.22" netssh --dry-run fsn/web2
|
||||
|
||||
# eth0 holds the prod address, which sorts after mgmt: catches an ignored filter.
|
||||
sed -i 's/interface_name: mgmt0/interface_name: eth0/' "$XDG_CONFIG_HOME/netssh.yaml"
|
||||
expect_eq "interface_name picks the named interface" "ssh -l ops 10.231.2.13" netssh --dry-run fsn/fsn1-pve3.hoster.test
|
||||
|
||||
config <<'EOF'
|
||||
cache: {ttl: 0}
|
||||
resolver:
|
||||
strategies: [hostname]
|
||||
hostname_domain: example.org
|
||||
ssh: {default_user: ops}
|
||||
EOF
|
||||
expect_eq "hostname strategy" "ssh -l ops fsn1-pve1.hoster.test" netssh --dry-run fsn/fsn1-pve1.hoster.test
|
||||
expect_eq "hostname connects via DNS" "fsn1-pve1" netssh fsn/fsn1-pve1.hoster.test hostname
|
||||
expect_eq "hostname domain for names without a dot" "ssh -l ops lab-db1.example.org" netssh --dry-run lab/lab-db1
|
||||
|
||||
config <<'EOF'
|
||||
cache: {ttl: 0}
|
||||
resolver:
|
||||
strategies: [interface_name]
|
||||
interface_name: mgmt0
|
||||
EOF
|
||||
expect_fail "no strategy finds an address" "no strategy resolved an IP" netssh --dry-run fsn/web1
|
||||
Reference in new issue
Block a user