Skip to content

Commit 8e642cd

Browse files
authored
RSDK-9863 Add ListTunnels wrappers (viamrobotics#4821)
1 parent 870940c commit 8e642cd

File tree

10 files changed

+111
-15
lines changed

10 files changed

+111
-15
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ require (
7575
go.uber.org/atomic v1.11.0
7676
go.uber.org/multierr v1.11.0
7777
go.uber.org/zap v1.27.0
78-
go.viam.com/api v0.1.396
78+
go.viam.com/api v0.1.397
7979
go.viam.com/test v1.2.4
8080
go.viam.com/utils v0.1.130
8181
goji.io v2.0.2+incompatible

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -1513,8 +1513,8 @@ go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
15131513
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
15141514
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
15151515
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
1516-
go.viam.com/api v0.1.396 h1:HqX+zt24BJFPcIQZk1fttDR6goiRCTt1pcVZyBOi7n4=
1517-
go.viam.com/api v0.1.396/go.mod h1:drvlBWaiHFxPziz5jayHvibez1qG7lylcNCC1LF8onU=
1516+
go.viam.com/api v0.1.397 h1:BGHQ71TmGDtUOWSmY66STA8/hcbUFV+okWAtgYVK7SA=
1517+
go.viam.com/api v0.1.397/go.mod h1:drvlBWaiHFxPziz5jayHvibez1qG7lylcNCC1LF8onU=
15181518
go.viam.com/test v1.2.4 h1:JYgZhsuGAQ8sL9jWkziAXN9VJJiKbjoi9BsO33TW3ug=
15191519
go.viam.com/test v1.2.4/go.mod h1:zI2xzosHdqXAJ/kFqcN+OIF78kQuTV2nIhGZ8EzvaJI=
15201520
go.viam.com/utils v0.1.130 h1:5vggHNK/ar/YHXjf9z5WuihX+n9jYFnA2CEFOYi99d8=

robot/client/client.go

+24-5
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,30 @@ func (rc *RobotClient) Tunnel(ctx context.Context, conn io.ReadWriteCloser, dest
13061306
return errors.Join(err, readerSenderErr, recvWriterErr)
13071307
}
13081308

1309+
// ListTunnels lists all available tunnels configured on the robot.
1310+
func (rc *RobotClient) ListTunnels(ctx context.Context) ([]config.TrafficTunnelEndpoint, error) {
1311+
var ttes []config.TrafficTunnelEndpoint
1312+
1313+
resp, err := rc.client.ListTunnels(ctx, &pb.ListTunnelsRequest{})
1314+
if err != nil {
1315+
return ttes, err
1316+
}
1317+
1318+
for _, protoTTE := range resp.Tunnels {
1319+
if protoTTE == nil {
1320+
continue
1321+
}
1322+
1323+
tte := config.TrafficTunnelEndpoint{
1324+
Port: int(protoTTE.Port),
1325+
ConnectionTimeout: protoTTE.ConnectionTimeout.AsDuration(),
1326+
}
1327+
ttes = append(ttes, tte)
1328+
}
1329+
1330+
return ttes, nil
1331+
}
1332+
13091333
// SetPeerConnection is only to be called internally from modules.
13101334
func (rc *RobotClient) SetPeerConnection(pc *webrtc.PeerConnection) {
13111335
rc.mu.Lock()
@@ -1366,8 +1390,3 @@ func streamClientInterceptor() googlegrpc.StreamClientInterceptor {
13661390
return streamer(ctx, desc, cc, method, opts...)
13671391
}
13681392
}
1369-
1370-
// ListTunnels is a no-op (returns nil) for robot clients.
1371-
func (rc *RobotClient) ListTunnels() []config.TrafficTunnelEndpoint {
1372-
return nil
1373-
}

robot/client/client_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -2286,3 +2286,49 @@ func TestVersion(t *testing.T) {
22862286
test.That(t, err, test.ShouldBeNil)
22872287
test.That(t, md, test.ShouldResemble, version)
22882288
}
2289+
2290+
func TestListTunnels(t *testing.T) {
2291+
logger := logging.NewTestLogger(t)
2292+
listener, err := net.Listen("tcp", "localhost:0")
2293+
test.That(t, err, test.ShouldBeNil)
2294+
gServer := grpc.NewServer()
2295+
2296+
expectedTTEs := []config.TrafficTunnelEndpoint{
2297+
{
2298+
Port: 9090,
2299+
ConnectionTimeout: 20 * time.Second,
2300+
},
2301+
{
2302+
Port: 27017,
2303+
ConnectionTimeout: 40 * time.Millisecond,
2304+
},
2305+
{
2306+
Port: 23654,
2307+
},
2308+
}
2309+
injectRobot := &inject.Robot{
2310+
ResourceNamesFunc: func() []resource.Name { return nil },
2311+
ResourceRPCAPIsFunc: func() []resource.RPCAPI { return nil },
2312+
MachineStatusFunc: func(ctx context.Context) (robot.MachineStatus, error) {
2313+
return robot.MachineStatus{State: robot.StateRunning}, nil
2314+
},
2315+
ListTunnelsFunc: func(ctx context.Context) ([]config.TrafficTunnelEndpoint, error) {
2316+
return expectedTTEs, nil
2317+
},
2318+
}
2319+
2320+
pb.RegisterRobotServiceServer(gServer, server.New(injectRobot))
2321+
2322+
go gServer.Serve(listener)
2323+
defer gServer.Stop()
2324+
2325+
client, err := New(context.Background(), listener.Addr().String(), logger)
2326+
test.That(t, err, test.ShouldBeNil)
2327+
defer func() {
2328+
test.That(t, client.Close(context.Background()), test.ShouldBeNil)
2329+
}()
2330+
2331+
ttes, err := client.ListTunnels(context.Background())
2332+
test.That(t, err, test.ShouldBeNil)
2333+
test.That(t, ttes, test.ShouldResemble, expectedTTEs)
2334+
}

robot/impl/local_robot.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1590,10 +1590,10 @@ func (r *localRobot) RestartAllowed() bool {
15901590
}
15911591

15921592
// ListTunnels returns information on available traffic tunnels.
1593-
func (r *localRobot) ListTunnels() []config.TrafficTunnelEndpoint {
1593+
func (r *localRobot) ListTunnels(_ context.Context) ([]config.TrafficTunnelEndpoint, error) {
15941594
cfg := r.Config()
15951595
if cfg != nil {
1596-
return cfg.Network.NetworkConfigData.TrafficTunnelEndpoints
1596+
return cfg.Network.NetworkConfigData.TrafficTunnelEndpoints, nil
15971597
}
1598-
return nil
1598+
return nil, nil
15991599
}

robot/impl/local_robot_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -4640,6 +4640,7 @@ func TestListTunnels(t *testing.T) {
46404640

46414641
r := setupLocalRobot(t, ctx, cfg, logger)
46424642

4643-
ttes := r.ListTunnels()
4643+
ttes, err := r.ListTunnels(ctx)
4644+
test.That(t, err, test.ShouldBeNil)
46444645
test.That(t, ttes, test.ShouldResemble, trafficTunnelEndpoints)
46454646
}

robot/impl/resource_manager_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2037,8 +2037,8 @@ func (rr *dummyRobot) Version(ctx context.Context) (robot.VersionResponse, error
20372037
}
20382038

20392039
// ListTunnels returns information on available traffic tunnels.
2040-
func (rr *dummyRobot) ListTunnels() []config.TrafficTunnelEndpoint {
2041-
return nil
2040+
func (rr *dummyRobot) ListTunnels(_ context.Context) ([]config.TrafficTunnelEndpoint, error) {
2041+
return nil, nil
20422042
}
20432043

20442044
// managerForDummyRobot integrates all parts from a given robot except for its remotes.

robot/robot.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ type Robot interface {
157157
Version(ctx context.Context) (VersionResponse, error)
158158

159159
// ListTunnels returns information on available traffic tunnels.
160-
ListTunnels() []config.TrafficTunnelEndpoint
160+
ListTunnels(ctx context.Context) ([]config.TrafficTunnelEndpoint, error)
161161
}
162162

163163
// A LocalRobot is a Robot that can have its parts modified.

robot/server/server.go

+19
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,25 @@ func (s *Server) Tunnel(srv pb.RobotService_TunnelServer) error {
135135
return errors.Join(err, readerSenderErr, recvWriterErr)
136136
}
137137

138+
// ListTunnels lists all available tunnels on the server.
139+
func (s *Server) ListTunnels(ctx context.Context, req *pb.ListTunnelsRequest) (*pb.ListTunnelsResponse, error) {
140+
res := &pb.ListTunnelsResponse{}
141+
142+
ttes, err := s.robot.ListTunnels(ctx)
143+
if err != nil {
144+
return nil, err
145+
}
146+
147+
for _, tte := range ttes {
148+
res.Tunnels = append(res.Tunnels, &pb.Tunnel{
149+
Port: uint32(tte.Port),
150+
ConnectionTimeout: durationpb.New(tte.ConnectionTimeout),
151+
})
152+
}
153+
154+
return res, nil
155+
}
156+
138157
// GetOperations lists all running operations.
139158
func (s *Server) GetOperations(ctx context.Context, req *pb.GetOperationsRequest) (*pb.GetOperationsResponse, error) {
140159
me := operation.Get(ctx)

testutils/inject/robot.go

+11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type Robot struct {
5151
CloudMetadataFunc func(ctx context.Context) (cloud.Metadata, error)
5252
MachineStatusFunc func(ctx context.Context) (robot.MachineStatus, error)
5353
ShutdownFunc func(ctx context.Context) error
54+
ListTunnelsFunc func(ctx context.Context) ([]config.TrafficTunnelEndpoint, error)
5455

5556
ops *operation.Manager
5657
SessMgr session.Manager
@@ -316,6 +317,16 @@ func (r *Robot) Shutdown(ctx context.Context) error {
316317
return r.ShutdownFunc(ctx)
317318
}
318319

320+
// ListTunnels calls the injected ListTunnels or the real one.
321+
func (r *Robot) ListTunnels(ctx context.Context) ([]config.TrafficTunnelEndpoint, error) {
322+
r.Mu.RLock()
323+
defer r.Mu.RUnlock()
324+
if r.ListTunnelsFunc == nil {
325+
return r.LocalRobot.ListTunnels(ctx)
326+
}
327+
return r.ListTunnelsFunc(ctx)
328+
}
329+
319330
type noopSessionManager struct{}
320331

321332
func (m noopSessionManager) Start(ctx context.Context, ownerID string) (*session.Session, error) {

0 commit comments

Comments
 (0)