mirror of https://github.com/coder/coder.git
feat: add tailnet v2 API support to coordinate endpoint (#11228)
closes #10532 Adds v2 support to the /coordinate endpoint via a query parameter. v1 already has test cases, and we haven't implemented v2 at the client yet, so the only new test case is an unsupported version.
This commit is contained in:
parent
a41cbb0f03
commit
211e59bf65
|
@ -473,6 +473,11 @@ func New(options *Options) *API {
|
|||
Cache: wsconncache.New(api._dialWorkspaceAgentTailnet, 0),
|
||||
}
|
||||
}
|
||||
api.TailnetClientService, err = tailnet.NewClientService(
|
||||
api.Logger.Named("tailnetclient"), &api.TailnetCoordinator)
|
||||
if err != nil {
|
||||
api.Logger.Fatal(api.ctx, "failed to initialize tailnet client service", slog.Error(err))
|
||||
}
|
||||
|
||||
workspaceAppsLogger := options.Logger.Named("workspaceapps")
|
||||
if options.WorkspaceAppsStatsCollectorOptions.Logger == nil {
|
||||
|
@ -1061,6 +1066,7 @@ type API struct {
|
|||
Auditor atomic.Pointer[audit.Auditor]
|
||||
WorkspaceClientCoordinateOverride atomic.Pointer[func(rw http.ResponseWriter) bool]
|
||||
TailnetCoordinator atomic.Pointer[tailnet.Coordinator]
|
||||
TailnetClientService *tailnet.ClientService
|
||||
QuotaCommitter atomic.Pointer[proto.QuotaCommitter]
|
||||
// WorkspaceProxyHostsFn returns the hosts of healthy workspace proxies
|
||||
// for header reasons.
|
||||
|
|
|
@ -1387,6 +1387,21 @@ func (api *API) workspaceAgentClientCoordinate(rw http.ResponseWriter, r *http.R
|
|||
}
|
||||
}
|
||||
|
||||
version := "1.0"
|
||||
qv := r.URL.Query().Get("version")
|
||||
if qv != "" {
|
||||
version = qv
|
||||
}
|
||||
if err := tailnet.ValidateVersion(version); err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Unknown or unsupported API version",
|
||||
Validations: []codersdk.ValidationError{
|
||||
{Field: "version", Detail: err.Error()},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
api.WebsocketWaitMutex.Lock()
|
||||
api.WebsocketWaitGroup.Add(1)
|
||||
api.WebsocketWaitMutex.Unlock()
|
||||
|
@ -1407,8 +1422,8 @@ func (api *API) workspaceAgentClientCoordinate(rw http.ResponseWriter, r *http.R
|
|||
go httpapi.Heartbeat(ctx, conn)
|
||||
|
||||
defer conn.Close(websocket.StatusNormalClosure, "")
|
||||
err = (*api.TailnetCoordinator.Load()).ServeClient(wsNetConn, uuid.New(), workspaceAgent.ID)
|
||||
if err != nil {
|
||||
err = api.TailnetClientService.ServeClient(ctx, version, wsNetConn, uuid.New(), workspaceAgent.ID)
|
||||
if err != nil && !xerrors.Is(err, io.EOF) && !xerrors.Is(err, context.Canceled) {
|
||||
_ = conn.Close(websocket.StatusInternalError, err.Error())
|
||||
return
|
||||
}
|
||||
|
|
|
@ -444,6 +444,38 @@ func TestWorkspaceAgentTailnet(t *testing.T) {
|
|||
require.Equal(t, "test", strings.TrimSpace(string(output)))
|
||||
}
|
||||
|
||||
func TestWorkspaceAgentClientCoordinate_BadVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, db := coderdtest.NewWithDatabase(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
|
||||
OrganizationID: user.OrganizationID,
|
||||
OwnerID: user.UserID,
|
||||
}).WithAgent().Do()
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
agentToken, err := uuid.Parse(r.AgentToken)
|
||||
require.NoError(t, err)
|
||||
//nolint: gocritic // testing
|
||||
ao, err := db.GetWorkspaceAgentAndOwnerByAuthToken(dbauthz.AsSystemRestricted(ctx), agentToken)
|
||||
require.NoError(t, err)
|
||||
|
||||
//nolint: bodyclose // closed by ReadBodyAsError
|
||||
resp, err := client.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("api/v2/workspaceagents/%s/coordinate", ao.WorkspaceAgent.ID),
|
||||
nil,
|
||||
codersdk.WithQueryParam("version", "99.99"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
||||
err = codersdk.ReadBodyAsError(resp)
|
||||
var sdkErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &sdkErr)
|
||||
require.Equal(t, "Unknown or unsupported API version", sdkErr.Message)
|
||||
require.Len(t, sdkErr.Validations, 1)
|
||||
require.Equal(t, "version", sdkErr.Validations[0].Field)
|
||||
}
|
||||
|
||||
func TestWorkspaceAgentTailnetDirectDisabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue