@@ -3,7 +3,6 @@ package main
33import (
44 "bytes"
55 "context"
6- "fmt"
76 "io"
87 "os"
98 "reflect"
@@ -915,46 +914,43 @@ func TestAllEnvs(t *testing.T) {
915914 assert .Equal (t , unindent (expected ), unindent (buffer .String ()))
916915}
917916
918- func TestSudoCommand (t * testing.T ) {
917+ type SSHTestConfig struct {
918+ Env map [string ]string
919+ AuthMethod string // "key" or "password"
920+ KeyPath string
921+ Password string
922+ Script []string
923+ Expected string
924+ SudoAccess bool
925+ InsecureCipher bool
926+ RequireTty bool
927+ CommandTimeout time.Duration
928+ }
929+
930+ func runSSHContainerTest (t * testing.T , cfg SSHTestConfig ) {
931+ t .Helper ()
919932 ctx := context .Background ()
920933
921- pubKey , err := os .ReadFile ("./tests/.ssh/id_rsa.pub" )
922- if err != nil {
923- t .Fatalf ("Could not read public key file: %v" , err )
924- }
925- // Define the container request using the linuxserver/openssh-server image
926- // Configure user 'testuser' with password 'testpass'
927934 req := testcontainers.ContainerRequest {
928935 Image : "linuxserver/openssh-server:latest" ,
929- ExposedPorts : []string {"2222/tcp" }, // Default port for this image is 2222
930- Env : map [string ]string {
931- "USER_NAME" : "testuser" ,
932- "PASSWORD_ACCESS" : "false" , // Disable password authentication
933- "SUDO_ACCESS" : "true" , // Optional: grant sudo access
934- "PUBLIC_KEY" : string (pubKey ),
935- },
936- // Wait for the SSH port (2222) to be listening
937- WaitingFor : wait .ForListeningPort ("2222/tcp" ).WithStartupTimeout (180 * time .Second ),
936+ ExposedPorts : []string {"2222/tcp" },
937+ Env : cfg .Env ,
938+ WaitingFor : wait .ForListeningPort ("2222/tcp" ).WithStartupTimeout (180 * time .Second ),
938939 }
939940
940- // Create and start the container
941941 sshContainer , err := testcontainers .GenericContainer (ctx , testcontainers.GenericContainerRequest {
942942 ContainerRequest : req ,
943943 Started : true ,
944944 })
945- // Skip test if Docker is not available or container fails to start
946945 if err != nil {
947- // Provide more context on failure
948946 t .Skipf ("Could not start container with image %s: %v. Check Docker environment and image availability. Skipping test." , req .Image , err )
949947 }
950948 defer func () {
951949 if err := sshContainer .Terminate (ctx ); err != nil {
952- // Log termination errors but don't fail the test for this
953950 t .Logf ("Could not terminate container: %v" , err )
954951 }
955952 }()
956953
957- // Get the mapped host and port for 2222/tcp
958954 host , err := sshContainer .Host (ctx )
959955 if err != nil {
960956 t .Fatalf ("Could not get container host: %v" , err )
@@ -963,31 +959,74 @@ func TestSudoCommand(t *testing.T) {
963959 if err != nil {
964960 t .Fatalf ("Could not get container mapped port 2222/tcp: %v" , err )
965961 }
966- var (
967- buffer bytes.Buffer
968- expected = `
969- root
970- `
971- )
962+
963+ var buffer bytes.Buffer
964+
965+ pluginCfg := Config {
966+ Host : []string {host },
967+ Username : "testuser" ,
968+ Port : port .Int (),
969+ Script : cfg .Script ,
970+ CommandTimeout : cfg .CommandTimeout ,
971+ UseInsecureCipher : cfg .InsecureCipher ,
972+ RequireTty : cfg .RequireTty ,
973+ }
974+ if pluginCfg .CommandTimeout == 0 {
975+ pluginCfg .CommandTimeout = 10 * time .Second
976+ }
977+ if cfg .AuthMethod == "key" {
978+ pluginCfg .KeyPath = cfg .KeyPath
979+ } else if cfg .AuthMethod == "password" {
980+ pluginCfg .Password = cfg .Password
981+ }
972982
973983 plugin := Plugin {
974- Config : Config {
975- Host : []string {host },
976- Username : "testuser" , // Use the configured username
977- Port : port .Int (), // Use the mapped port
978- KeyPath : "./tests/.ssh/id_rsa" ,
979- Script : []string {
980- `sudo su - -c "whoami"` ,
981- },
982- CommandTimeout : 10 * time .Second ,
983- RequireTty : true ,
984- UseInsecureCipher : true , // Allow insecure ciphers for compatibility
985- },
984+ Config : pluginCfg ,
986985 Writer : & buffer ,
987986 }
988987
989988 assert .Nil (t , plugin .Exec ())
990- assert .Equal (t , unindent (expected ), unindent (buffer .String ()))
989+ assert .Equal (t , unindent (cfg .Expected ), unindent (buffer .String ()))
990+ }
991+
992+ func TestSudoCommand (t * testing.T ) {
993+ pubKey , err := os .ReadFile ("./tests/.ssh/id_rsa.pub" )
994+ if err != nil {
995+ t .Fatalf ("Could not read public key file: %v" , err )
996+ }
997+ runSSHContainerTest (t , SSHTestConfig {
998+ Env : map [string ]string {
999+ "USER_NAME" : "testuser" ,
1000+ "PASSWORD_ACCESS" : "false" ,
1001+ "SUDO_ACCESS" : "true" ,
1002+ "PUBLIC_KEY" : string (pubKey ),
1003+ },
1004+ AuthMethod : "key" ,
1005+ KeyPath : "./tests/.ssh/id_rsa" ,
1006+ Script : []string {`sudo su - -c "whoami"` },
1007+ Expected : "root" ,
1008+ SudoAccess : true ,
1009+ InsecureCipher : true ,
1010+ RequireTty : true ,
1011+ CommandTimeout : 10 * time .Second ,
1012+ })
1013+ }
1014+
1015+ func TestSSHWithTestcontainers (t * testing.T ) {
1016+ runSSHContainerTest (t , SSHTestConfig {
1017+ Env : map [string ]string {
1018+ "USER_NAME" : "testuser" ,
1019+ "USER_PASSWORD" : "testpass" ,
1020+ "PASSWORD_ACCESS" : "true" ,
1021+ "SUDO_ACCESS" : "false" ,
1022+ },
1023+ AuthMethod : "password" ,
1024+ Password : "testpass" ,
1025+ Script : []string {"whoami" },
1026+ Expected : "testuser" ,
1027+ InsecureCipher : true ,
1028+ CommandTimeout : 60 * time .Second ,
1029+ })
9911030}
9921031
9931032func TestCommandWithIPv6 (t * testing.T ) {
@@ -1015,73 +1054,3 @@ func TestCommandWithIPv6(t *testing.T) {
10151054 assert .Nil (t , plugin .Exec ())
10161055 assert .Equal (t , unindent (expected ), unindent (buffer .String ()))
10171056}
1018-
1019- func TestSSHWithTestcontainers (t * testing.T ) {
1020- ctx := context .Background ()
1021-
1022- // Define the container request using the linuxserver/openssh-server image
1023- // Configure user 'testuser' with password 'testpass'
1024- req := testcontainers.ContainerRequest {
1025- Image : "linuxserver/openssh-server:latest" ,
1026- ExposedPorts : []string {"2222/tcp" }, // Default port for this image is 2222
1027- Env : map [string ]string {
1028- "USER_NAME" : "testuser" ,
1029- "USER_PASSWORD" : "testpass" ,
1030- "PASSWORD_ACCESS" : "true" , // Enable password authentication
1031- "SUDO_ACCESS" : "false" , // Optional: grant sudo access
1032- },
1033- // Wait for the SSH port (2222) to be listening
1034- WaitingFor : wait .ForListeningPort ("2222/tcp" ).WithStartupTimeout (180 * time .Second ),
1035- }
1036-
1037- // Create and start the container
1038- sshContainer , err := testcontainers .GenericContainer (ctx , testcontainers.GenericContainerRequest {
1039- ContainerRequest : req ,
1040- Started : true ,
1041- })
1042- // Skip test if Docker is not available or container fails to start
1043- if err != nil {
1044- // Provide more context on failure
1045- t .Skipf ("Could not start container with image %s: %v. Check Docker environment and image availability. Skipping test." , req .Image , err )
1046- }
1047- defer func () {
1048- if err := sshContainer .Terminate (ctx ); err != nil {
1049- // Log termination errors but don't fail the test for this
1050- t .Logf ("Could not terminate container: %v" , err )
1051- }
1052- }()
1053-
1054- // Get the mapped host and port for 2222/tcp
1055- host , err := sshContainer .Host (ctx )
1056- if err != nil {
1057- t .Fatalf ("Could not get container host: %v" , err )
1058- }
1059- port , err := sshContainer .MappedPort (ctx , "2222/tcp" )
1060- if err != nil {
1061- t .Fatalf ("Could not get container mapped port 2222/tcp: %v" , err )
1062- }
1063-
1064- var buffer bytes.Buffer
1065- expected := `testuser` // The user we configured
1066-
1067- plugin := Plugin {
1068- Config : Config {
1069- Host : []string {host },
1070- Username : "testuser" , // Use the configured username
1071- Port : port .Int (), // Use the mapped port
1072- Password : "testpass" , // Use the configured password
1073- Script : []string {"whoami" },
1074- CommandTimeout : 60 * time .Second ,
1075- UseInsecureCipher : true , // Allow insecure ciphers for compatibility
1076- },
1077- Writer : & buffer ,
1078- }
1079-
1080- t .Logf ("Attempting SSH connection to %s:%d as user %s" , host , port .Int (), plugin .Config .Username )
1081- err = plugin .Exec ()
1082- t .Logf ("SSH command output: %s" , buffer .String ())
1083- t .Logf ("SSH command error: %v" , err )
1084-
1085- assert .Nil (t , err , fmt .Sprintf ("plugin.Exec failed: %v" , err ))
1086- assert .Equal (t , unindent (expected ), unindent (buffer .String ()))
1087- }
0 commit comments