add ProxyJump function
This commit is contained in:
1 parent
56e20e5464
commit
7f0e0fdb23
48 files changed
+3875
-44
No files matched your search
@@ -0,0 +1,101 @@
|
||||
package keymgr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"ssh-access-tui/internal/model"
|
||||
)
|
||||
|
||||
// extract7z unpacks archivePath (encrypted with password) into a fresh temp
|
||||
// dir and returns that dir. Skips the test if 7z is unavailable rather than
|
||||
// failing, since this is exercising an external tool, not this package.
|
||||
func extract7z(t *testing.T, archivePath, password string) string {
|
||||
t.Helper()
|
||||
if _, err := exec.LookPath("7z"); err != nil {
|
||||
t.Skip("7z not available in PATH")
|
||||
}
|
||||
dest := t.TempDir()
|
||||
cmd := exec.Command("7z", "x", "-p"+password, "-o"+dest, archivePath)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("7z x: %v: %s", err, out)
|
||||
}
|
||||
return dest
|
||||
}
|
||||
|
||||
// TestBuildUserArchive_ProxyJumpSelectsRenderer is a smoke test verifying
|
||||
// that BuildUserArchive's new proxyJump parameter actually switches which
|
||||
// client config / instructions renderer gets packed, end to end through the
|
||||
// real ssh-keygen/7z tools (see internal/keymgr package doc: the private key
|
||||
// only exists transiently on disk for this one operation).
|
||||
func TestBuildUserArchive_ProxyJumpSelectsRenderer(t *testing.T) {
|
||||
if _, err := exec.LookPath("ssh-keygen"); err != nil {
|
||||
t.Skip("ssh-keygen not available in PATH")
|
||||
}
|
||||
if _, err := exec.LookPath("7z"); err != nil {
|
||||
t.Skip("7z not available in PATH")
|
||||
}
|
||||
|
||||
forwards := []model.Forward{
|
||||
{HostName: "db-prod-1", Address: "10.0.0.5", Port: 22, ServiceName: "ssh"},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
proxyJump bool
|
||||
}{
|
||||
{"LocalForward mode", false},
|
||||
{"ProxyJump mode", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
scratch := t.TempDir()
|
||||
outDir := t.TempDir()
|
||||
username := "test-user"
|
||||
password := "TestPassw0rd123"
|
||||
|
||||
res, err := BuildUserArchive(scratch, outDir, "bastion.example.com", 2222, username, password, forwards, tt.proxyJump)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildUserArchive: %v", err)
|
||||
}
|
||||
if res.ArchivePath == "" {
|
||||
t.Fatalf("expected non-empty archive path")
|
||||
}
|
||||
if _, err := os.Stat(res.ArchivePath); err != nil {
|
||||
t.Fatalf("archive not found on disk: %v", err)
|
||||
}
|
||||
|
||||
// Scratch dir must be wiped (private key must not linger).
|
||||
if entries, err := os.ReadDir(filepath.Join(scratch, username)); err == nil {
|
||||
t.Fatalf("expected scratch dir to be wiped, still has entries: %v", entries)
|
||||
}
|
||||
|
||||
extractedDir := extract7z(t, res.ArchivePath, password)
|
||||
cfgBytes, err := os.ReadFile(filepath.Join(extractedDir, "config"))
|
||||
if err != nil {
|
||||
t.Fatalf("read extracted config: %v", err)
|
||||
}
|
||||
cfg := string(cfgBytes)
|
||||
|
||||
if tt.proxyJump {
|
||||
if strings.Contains(cfg, "LocalForward") {
|
||||
t.Errorf("proxyJump=true archive must not contain LocalForward, got config:\n%s", cfg)
|
||||
}
|
||||
if !strings.Contains(cfg, "ProxyJump jump") {
|
||||
t.Errorf("proxyJump=true archive must contain ProxyJump jump, got config:\n%s", cfg)
|
||||
}
|
||||
} else {
|
||||
if strings.Contains(cfg, "ProxyJump") {
|
||||
t.Errorf("proxyJump=false archive must not contain ProxyJump, got config:\n%s", cfg)
|
||||
}
|
||||
if !strings.Contains(cfg, "LocalForward") {
|
||||
t.Errorf("proxyJump=false archive must contain LocalForward, got config:\n%s", cfg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user