|
1 | 1 | package externalproxy
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "context" |
4 | 5 | "net/http"
|
5 | 6 | "net/url"
|
6 | 7 | "regexp"
|
7 | 8 | "time"
|
8 | 9 |
|
| 10 | + "github.com/google/uuid" |
| 11 | + |
| 12 | + "github.com/coder/coder/codersdk" |
| 13 | + |
9 | 14 | "github.com/coder/coder/buildinfo"
|
10 | 15 |
|
11 | 16 | "github.com/prometheus/client_golang/prometheus"
|
@@ -75,36 +80,56 @@ type Server struct {
|
75 | 80 | // - derpserver
|
76 | 81 |
|
77 | 82 | Options *Options
|
| 83 | + // SDKClient is a client to the primary coderd instance. |
| 84 | + // TODO: We really only need 'DialWorkspaceAgent', so maybe just pass that? |
| 85 | + SDKClient *codersdk.Client |
| 86 | + |
| 87 | + // Used for graceful shutdown. |
| 88 | + // Required for the dialer. |
| 89 | + ctx context.Context |
| 90 | + cancel context.CancelFunc |
78 | 91 | }
|
79 | 92 |
|
80 | 93 | func New(opts *Options) *Server {
|
81 | 94 | if opts.PrometheusRegistry == nil {
|
82 | 95 | opts.PrometheusRegistry = prometheus.NewRegistry()
|
83 | 96 | }
|
84 | 97 |
|
| 98 | + client := codersdk.New(opts.PrimaryAccessURL) |
| 99 | + // TODO: @emyrk we need to implement some form of authentication for the |
| 100 | + // external proxy to the the primary. This allows us to make workspace |
| 101 | + // connections. |
| 102 | + // Ideally we reuse the same client as the cli, but this can be changed. |
| 103 | + // If the auth fails, we need some logic to retry and make sure this client |
| 104 | + // is always authenticated and usable. |
| 105 | + client.SetSessionToken("fake-token") |
| 106 | + |
85 | 107 | r := chi.NewRouter()
|
| 108 | + ctx, cancel := context.WithCancel(context.Background()) |
86 | 109 | s := &Server{
|
87 |
| - Options: opts, |
88 |
| - PrimaryAccessURL: opts.PrimaryAccessURL, |
89 |
| - AppServer: &workspaceapps.Server{ |
90 |
| - Logger: opts.Logger.Named("workspaceapps"), |
91 |
| - DashboardURL: opts.PrimaryAccessURL, |
92 |
| - AccessURL: opts.AccessURL, |
93 |
| - Hostname: opts.AppHostname, |
94 |
| - HostnameRegex: opts.AppHostnameRegex, |
95 |
| - // TODO: @emyrk We should reduce the options passed in here. |
96 |
| - DeploymentValues: nil, |
97 |
| - RealIPConfig: opts.RealIPConfig, |
98 |
| - // TODO: @emyrk we need to implement this for external token providers. |
99 |
| - SignedTokenProvider: nil, |
100 |
| - // TODO: @emyrk we need to implement a dialer |
101 |
| - WorkspaceConnCache: wsconncache.New(nil, 0), |
102 |
| - AppSecurityKey: opts.AppSecurityKey, |
103 |
| - }, |
| 110 | + Options: opts, |
| 111 | + PrimaryAccessURL: opts.PrimaryAccessURL, |
104 | 112 | Logger: opts.Logger.Named("workspace-proxy"),
|
105 | 113 | TracerProvider: opts.Tracing,
|
106 | 114 | PrometheusRegistry: opts.PrometheusRegistry,
|
107 | 115 | Handler: r,
|
| 116 | + ctx: ctx, |
| 117 | + cancel: cancel, |
| 118 | + } |
| 119 | + |
| 120 | + s.AppServer = &workspaceapps.Server{ |
| 121 | + Logger: opts.Logger.Named("workspaceapps"), |
| 122 | + DashboardURL: opts.PrimaryAccessURL, |
| 123 | + AccessURL: opts.AccessURL, |
| 124 | + Hostname: opts.AppHostname, |
| 125 | + HostnameRegex: opts.AppHostnameRegex, |
| 126 | + // TODO: @emyrk We should reduce the options passed in here. |
| 127 | + DeploymentValues: nil, |
| 128 | + RealIPConfig: opts.RealIPConfig, |
| 129 | + // TODO: @emyrk we need to implement this for external token providers. |
| 130 | + SignedTokenProvider: nil, |
| 131 | + WorkspaceConnCache: wsconncache.New(s.DialWorkspaceAgent, 0), |
| 132 | + AppSecurityKey: opts.AppSecurityKey, |
108 | 133 | }
|
109 | 134 |
|
110 | 135 | // Routes
|
@@ -157,5 +182,10 @@ func New(opts *Options) *Server {
|
157 | 182 | }
|
158 | 183 |
|
159 | 184 | func (s *Server) Close() error {
|
| 185 | + s.cancel() |
160 | 186 | return s.AppServer.Close()
|
161 | 187 | }
|
| 188 | + |
| 189 | +func (s *Server) DialWorkspaceAgent(id uuid.UUID) (*codersdk.WorkspaceAgentConn, error) { |
| 190 | + return s.SDKClient.DialWorkspaceAgent(s.ctx, id, nil) |
| 191 | +} |
0 commit comments