Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/local-app/pkg/bastion/service.go
2500 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package bastion
6
7
import (
8
"context"
9
10
"google.golang.org/grpc/codes"
11
"google.golang.org/grpc/status"
12
13
"github.com/gitpod-io/gitpod/local-app/api"
14
)
15
16
type LocalAppService struct {
17
b *Bastion
18
s *SSHConfigWritingCallback
19
api.UnimplementedLocalAppServer
20
}
21
22
func NewLocalAppService(b *Bastion, s *SSHConfigWritingCallback) *LocalAppService {
23
return &LocalAppService{
24
b: b,
25
s: s,
26
}
27
}
28
29
func (s *LocalAppService) TunnelStatus(req *api.TunnelStatusRequest, srv api.LocalApp_TunnelStatusServer) error {
30
if !req.Observe {
31
return srv.Send(&api.TunnelStatusResponse{
32
Tunnels: s.b.Status(req.InstanceId),
33
})
34
}
35
36
sub, err := s.b.Subscribe(req.InstanceId)
37
if err == ErrTooManySubscriptions {
38
return status.Error(codes.ResourceExhausted, "too many subscriptions")
39
}
40
if err != nil {
41
return status.Error(codes.Internal, err.Error())
42
}
43
defer sub.Close()
44
45
for {
46
select {
47
case <-srv.Context().Done():
48
return nil
49
case update := <-sub.Updates():
50
if update == nil {
51
return nil
52
}
53
err := srv.Send(&api.TunnelStatusResponse{
54
Tunnels: update,
55
})
56
if err != nil {
57
return err
58
}
59
}
60
}
61
}
62
63
func (s *LocalAppService) AutoTunnel(ctx context.Context, req *api.AutoTunnelRequest) (*api.AutoTunnelResponse, error) {
64
s.b.AutoTunnel(req.InstanceId, req.Enabled)
65
return &api.AutoTunnelResponse{}, nil
66
}
67
68
func (s *LocalAppService) ResolveSSHConnection(ctx context.Context, req *api.ResolveSSHConnectionRequest) (*api.ResolveSSHConnectionResponse, error) {
69
ws := s.b.Update(req.WorkspaceId)
70
if ws == nil || ws.InstanceID != req.InstanceId {
71
return nil, status.Error(codes.NotFound, "workspace not found")
72
}
73
if ws.localSSHListener == nil {
74
return nil, status.Error(codes.NotFound, "workspace ssh tunnel not configured")
75
}
76
return &api.ResolveSSHConnectionResponse{
77
Host: ws.WorkspaceID,
78
ConfigFile: s.s.Path,
79
}, nil
80
}
81
82