1
1
package cli_test
2
2
3
3
import (
4
+ "context"
5
+ "io"
6
+ "net"
4
7
"os"
5
8
"os/exec"
6
9
"path/filepath"
7
10
"strings"
8
11
"testing"
9
- "time"
10
12
11
- "cdr.dev/slog/sloggers/slogtest"
12
13
"github.com/google/uuid"
13
14
"github.com/stretchr/testify/require"
14
15
16
+ "cdr.dev/slog/sloggers/slogtest"
17
+
15
18
"github.com/coder/coder/agent"
16
19
"github.com/coder/coder/cli/clitest"
17
20
"github.com/coder/coder/coderd/coderdtest"
@@ -24,82 +27,98 @@ import (
24
27
25
28
func TestConfigSSH (t * testing.T ) {
26
29
t .Parallel ()
27
- binPath := filepath .Join (t .TempDir (), "coder" )
28
- _ , err := exec .Command ("go" , "build" , "-o" , binPath , "github.com/coder/coder/cmd/coder" ).CombinedOutput ()
29
- require .NoError (t , err )
30
-
31
- t .Run ("Dial" , func (t * testing.T ) {
32
- t .Parallel ()
33
- client := coderdtest .New (t , nil )
34
- user := coderdtest .CreateFirstUser (t , client )
35
- coderdtest .NewProvisionerDaemon (t , client )
36
- authToken := uuid .NewString ()
37
- version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , & echo.Responses {
38
- Parse : echo .ParseComplete ,
39
- ProvisionDryRun : []* proto.Provision_Response {{
40
- Type : & proto.Provision_Response_Complete {
41
- Complete : & proto.Provision_Complete {
42
- Resources : []* proto.Resource {{
30
+ client := coderdtest .New (t , nil )
31
+ user := coderdtest .CreateFirstUser (t , client )
32
+ coderdtest .NewProvisionerDaemon (t , client )
33
+ authToken := uuid .NewString ()
34
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , & echo.Responses {
35
+ Parse : echo .ParseComplete ,
36
+ ProvisionDryRun : []* proto.Provision_Response {{
37
+ Type : & proto.Provision_Response_Complete {
38
+ Complete : & proto.Provision_Complete {
39
+ Resources : []* proto.Resource {{
40
+ Name : "example" ,
41
+ Type : "aws_instance" ,
42
+ Agents : []* proto.Agent {{
43
+ Id : uuid .NewString (),
43
44
Name : "example" ,
44
- Type : "aws_instance" ,
45
- Agents : []* proto.Agent {{
46
- Id : uuid .NewString (),
47
- Name : "example" ,
48
- }},
49
45
}},
50
- },
46
+ }} ,
51
47
},
52
- }},
53
- Provision : []* proto.Provision_Response {{
54
- Type : & proto.Provision_Response_Complete {
55
- Complete : & proto.Provision_Complete {
56
- Resources : []* proto.Resource {{
48
+ },
49
+ }},
50
+ Provision : []* proto.Provision_Response {{
51
+ Type : & proto.Provision_Response_Complete {
52
+ Complete : & proto.Provision_Complete {
53
+ Resources : []* proto.Resource {{
54
+ Name : "example" ,
55
+ Type : "aws_instance" ,
56
+ Agents : []* proto.Agent {{
57
+ Id : uuid .NewString (),
57
58
Name : "example" ,
58
- Type : "aws_instance" ,
59
- Agents : []* proto.Agent {{
60
- Id : uuid .NewString (),
61
- Name : "example" ,
62
- Auth : & proto.Agent_Token {
63
- Token : authToken ,
64
- },
65
- }},
59
+ Auth : & proto.Agent_Token {
60
+ Token : authToken ,
61
+ },
66
62
}},
67
- },
63
+ }} ,
68
64
},
69
- }},
70
- })
71
- coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
72
- template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
73
- workspace := coderdtest .CreateWorkspace (t , client , codersdk .Me , template .ID )
74
- coderdtest .AwaitWorkspaceBuildJob (t , client , workspace .LatestBuild .ID )
75
- agentClient := codersdk .New (client .URL )
76
- agentClient .SessionToken = authToken
77
- agentCloser := agent .New (agentClient .ListenWorkspaceAgent , & peer.ConnOptions {
78
- Logger : slogtest .Make (t , nil ),
79
- })
80
- t .Cleanup (func () {
81
- _ = agentCloser .Close ()
82
- })
83
- tempFile , err := os .CreateTemp (t .TempDir (), "" )
84
- require .NoError (t , err )
85
- _ = tempFile .Close ()
86
- cmd , root := clitest .New (t , "config-ssh" , "--binary-file" , binPath , "--ssh-config-file" , tempFile .Name ())
87
- clitest .SetupConfig (t , client , root )
88
- doneChan := make (chan struct {})
89
- pty := ptytest .New (t )
90
- cmd .SetIn (pty .Input ())
91
- cmd .SetOut (pty .Output ())
92
- go func () {
93
- defer close (doneChan )
94
- err := cmd .Execute ()
65
+ },
66
+ }},
67
+ })
68
+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
69
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
70
+ workspace := coderdtest .CreateWorkspace (t , client , codersdk .Me , template .ID )
71
+ coderdtest .AwaitWorkspaceBuildJob (t , client , workspace .LatestBuild .ID )
72
+ agentClient := codersdk .New (client .URL )
73
+ agentClient .SessionToken = authToken
74
+ agentCloser := agent .New (agentClient .ListenWorkspaceAgent , & peer.ConnOptions {
75
+ Logger : slogtest .Make (t , nil ),
76
+ })
77
+ t .Cleanup (func () {
78
+ _ = agentCloser .Close ()
79
+ })
80
+ tempFile , err := os .CreateTemp (t .TempDir (), "" )
81
+ require .NoError (t , err )
82
+ _ = tempFile .Close ()
83
+ resources := coderdtest .AwaitWorkspaceAgents (t , client , workspace .LatestBuild .ID )
84
+ agentConn , err := client .DialWorkspaceAgent (context .Background (), resources [0 ].Agents [0 ].ID , nil , nil )
85
+ require .NoError (t , err )
86
+ defer agentConn .Close ()
87
+ socket := filepath .Join (t .TempDir (), "ssh" )
88
+ listener , err := net .Listen ("unix" , socket )
89
+ require .NoError (t , err )
90
+ go func () {
91
+ for {
92
+ conn , err := listener .Accept ()
93
+ if err != nil {
94
+ return
95
+ }
96
+ ssh , err := agentConn .SSH ()
95
97
require .NoError (t , err )
96
- }()
97
- <- doneChan
98
- t .Log (tempFile .Name ())
99
- time .Sleep (time .Hour )
100
- output , err := exec .Command ("ssh" , "-F" , tempFile .Name (), "coder." + workspace .Name , "echo" , "test" ).Output ()
101
- t .Log (string (output ))
102
- require .NoError (t , err )
103
- require .Equal (t , "test" , strings .TrimSpace (string (output )))
98
+ go io .Copy (conn , ssh )
99
+ go io .Copy (ssh , conn )
100
+ }
101
+ }()
102
+ t .Cleanup (func () {
103
+ _ = listener .Close ()
104
104
})
105
+
106
+ cmd , root := clitest .New (t , "config-ssh" , "--ssh-option" , "ProxyCommand socat - UNIX-CLIENT:" + socket , "--ssh-config-file" , tempFile .Name ())
107
+ clitest .SetupConfig (t , client , root )
108
+ doneChan := make (chan struct {})
109
+ pty := ptytest .New (t )
110
+ cmd .SetIn (pty .Input ())
111
+ cmd .SetOut (pty .Output ())
112
+ go func () {
113
+ defer close (doneChan )
114
+ err := cmd .Execute ()
115
+ require .NoError (t , err )
116
+ }()
117
+ <- doneChan
118
+
119
+ t .Log (tempFile .Name ())
120
+ // #nosec
121
+ data , err := exec .Command ("ssh" , "-F" , tempFile .Name (), "coder." + workspace .Name , "echo" , "test" ).Output ()
122
+ require .NoError (t , err )
123
+ require .Equal (t , "test" , strings .TrimSpace (string (data )))
105
124
}
0 commit comments