Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit85c3c4c

Browse files
authored
feat(tailnet): add alias with username and short alias to DNS (#15585)
Adds DNS aliases of the form `<agent>.<workspace>.<username>.coder.` and`<workspace>.coder.`
1 parentc3c23ed commit85c3c4c

File tree

2 files changed

+83
-48
lines changed

2 files changed

+83
-48
lines changed

‎tailnet/controllers.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ func (r *basicResumeTokenRefresher) refresh() {
858858
typetunnelAllWorkspaceUpdatesControllerstruct {
859859
coordCtrl*TunnelSrcCoordController
860860
dnsHostSetterDNSHostsSetter
861+
ownerUsernamestring
861862
logger slog.Logger
862863
}
863864

@@ -868,18 +869,30 @@ type workspace struct {
868869
}
869870

870871
// addAllDNSNames adds names for all of its agents to the given map of names
871-
func (wworkspace)addAllDNSNames(namesmap[dnsname.FQDN][]netip.Addr)error {
872+
func (wworkspace)addAllDNSNames(namesmap[dnsname.FQDN][]netip.Addr,ownerstring)error {
872873
for_,a:=rangew.agents {
873874
// TODO: technically, DNS labels cannot start with numbers, but the rules are often not
874875
// strictly enforced.
875-
// TODO: support <agent>.<workspace>.<username>.coder
876876
fqdn,err:=dnsname.ToFQDN(fmt.Sprintf("%s.%s.me.coder.",a.name,w.name))
877877
iferr!=nil {
878878
returnerr
879879
}
880880
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.id)}
881+
fqdn,err=dnsname.ToFQDN(fmt.Sprintf("%s.%s.%s.coder.",a.name,w.name,owner))
882+
iferr!=nil {
883+
returnerr
884+
}
885+
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.id)}
886+
}
887+
iflen(w.agents)==1 {
888+
fqdn,err:=dnsname.ToFQDN(fmt.Sprintf("%s.coder.",w.name))
889+
iferr!=nil {
890+
returnerr
891+
}
892+
for_,a:=rangew.agents {
893+
names[fqdn]= []netip.Addr{CoderServicePrefix.AddrFromUUID(a.id)}
894+
}
881895
}
882-
// TODO: Possibly support <workspace>.coder. alias if there is only one agent
883896
returnnil
884897
}
885898

@@ -895,6 +908,7 @@ func (t *tunnelAllWorkspaceUpdatesController) New(client WorkspaceUpdatesClient)
895908
logger:t.logger,
896909
coordCtrl:t.coordCtrl,
897910
dnsHostsSetter:t.dnsHostSetter,
911+
ownerUsername:t.ownerUsername,
898912
recvLoopDone:make(chanstruct{}),
899913
workspaces:make(map[uuid.UUID]*workspace),
900914
}
@@ -908,6 +922,7 @@ type tunnelUpdater struct {
908922
clientWorkspaceUpdatesClient
909923
coordCtrl*TunnelSrcCoordController
910924
dnsHostsSetterDNSHostsSetter
925+
ownerUsernamestring
911926
recvLoopDonechanstruct{}
912927

913928
// don't need the mutex since only manipulated by the recvLoop
@@ -1088,7 +1103,7 @@ func (t *tunnelUpdater) allAgentIDs() []uuid.UUID {
10881103
func (t*tunnelUpdater)allDNSNames()map[dnsname.FQDN][]netip.Addr {
10891104
names:=make(map[dnsname.FQDN][]netip.Addr)
10901105
for_,w:=ranget.workspaces {
1091-
err:=w.addAllDNSNames(names)
1106+
err:=w.addAllDNSNames(names,t.ownerUsername)
10921107
iferr!=nil {
10931108
// This should never happen in production, because converting the FQDN only fails
10941109
// if names are too long, and we put strict length limits on agent, workspace, and user
@@ -1102,13 +1117,28 @@ func (t *tunnelUpdater) allDNSNames() map[dnsname.FQDN][]netip.Addr {
11021117
returnnames
11031118
}
11041119

1120+
typeTunnelAllOptionfunc(t*tunnelAllWorkspaceUpdatesController)
1121+
1122+
// WithDNS configures the tunnelAllWorkspaceUpdatesController to set DNS names for all workspaces
1123+
// and agents it learns about.
1124+
funcWithDNS(dDNSHostsSetter,ownerUsernamestring)TunnelAllOption {
1125+
returnfunc(t*tunnelAllWorkspaceUpdatesController) {
1126+
t.dnsHostSetter=d
1127+
t.ownerUsername=ownerUsername
1128+
}
1129+
}
1130+
11051131
// NewTunnelAllWorkspaceUpdatesController creates a WorkspaceUpdatesController that creates tunnels
11061132
// (via the TunnelSrcCoordController) to all agents received over the WorkspaceUpdates RPC. If a
11071133
// DNSHostSetter is provided, it also programs DNS hosts based on the agent and workspace names.
11081134
funcNewTunnelAllWorkspaceUpdatesController(
1109-
logger slog.Logger,c*TunnelSrcCoordController,dDNSHostsSetter,
1135+
logger slog.Logger,c*TunnelSrcCoordController,opts...TunnelAllOption,
11101136
)WorkspaceUpdatesController {
1111-
return&tunnelAllWorkspaceUpdatesController{logger:logger,coordCtrl:c,dnsHostSetter:d}
1137+
t:=&tunnelAllWorkspaceUpdatesController{logger:logger,coordCtrl:c}
1138+
for_,opt:=rangeopts {
1139+
opt(t)
1140+
}
1141+
returnt
11121142
}
11131143

11141144
// NewController creates a new Controller without running it

‎tailnet/controllers_test.go

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -974,13 +974,13 @@ func (f *fakeResumeTokenClient) RefreshResumeToken(_ context.Context, _ *proto.R
974974
}
975975
select {
976976
case<-f.ctx.Done():
977-
returnnil,f.ctx.Err()
977+
returnnil,timeoutOnFakeErr
978978
casef.calls<-call:
979979
// OK
980980
}
981981
select {
982982
case<-f.ctx.Done():
983-
returnnil,f.ctx.Err()
983+
returnnil,timeoutOnFakeErr
984984
caseerr:=<-call.errCh:
985985
returnnil,err
986986
caseresp:=<-call.resp:
@@ -1240,6 +1240,11 @@ func (p *pipeDialer) Dial(_ context.Context, _ tailnet.ResumeTokenController) (t
12401240
},nil
12411241
}
12421242

1243+
// timeoutOnFakeErr is the error we send when fakes fail to send calls or receive responses before
1244+
// their context times out. We don't want to send the context error since that often doesn't trigger
1245+
// test failures or logging.
1246+
vartimeoutOnFakeErr=xerrors.New("test timeout")
1247+
12431248
typefakeCoordinatorClientstruct {
12441249
ctx context.Context
12451250
t testing.TB
@@ -1253,15 +1258,13 @@ func (f fakeCoordinatorClient) Close() error {
12531258
errs:=make(chanerror)
12541259
select {
12551260
case<-f.ctx.Done():
1256-
f.t.Error("timed out waiting to send close call")
1257-
returnf.ctx.Err()
1261+
returntimeoutOnFakeErr
12581262
casef.close<-errs:
12591263
// OK
12601264
}
12611265
select {
12621266
case<-f.ctx.Done():
1263-
f.t.Error("timed out waiting for close call response")
1264-
returnf.ctx.Err()
1267+
returntimeoutOnFakeErr
12651268
caseerr:=<-errs:
12661269
returnerr
12671270
}
@@ -1276,15 +1279,13 @@ func (f fakeCoordinatorClient) Send(request *proto.CoordinateRequest) error {
12761279
}
12771280
select {
12781281
case<-f.ctx.Done():
1279-
f.t.Error("timed out waiting to send call")
1280-
returnf.ctx.Err()
1282+
returntimeoutOnFakeErr
12811283
casef.reqs<-call:
12821284
// OK
12831285
}
12841286
select {
12851287
case<-f.ctx.Done():
1286-
f.t.Error("timed out waiting for send call response")
1287-
returnf.ctx.Err()
1288+
returntimeoutOnFakeErr
12881289
caseerr:=<-errs:
12891290
returnerr
12901291
}
@@ -1300,15 +1301,13 @@ func (f fakeCoordinatorClient) Recv() (*proto.CoordinateResponse, error) {
13001301
}
13011302
select {
13021303
case<-f.ctx.Done():
1303-
f.t.Error("timed out waiting to send Recv() call")
1304-
returnnil,f.ctx.Err()
1304+
returnnil,timeoutOnFakeErr
13051305
casef.resps<-call:
13061306
// OK
13071307
}
13081308
select {
13091309
case<-f.ctx.Done():
1310-
f.t.Error("timed out waiting for Recv() call response")
1311-
returnnil,f.ctx.Err()
1310+
returnnil,timeoutOnFakeErr
13121311
caseerr:=<-errs:
13131312
returnnil,err
13141313
caseresp:=<-resps:
@@ -1348,15 +1347,13 @@ func (f *fakeWorkspaceUpdateClient) Close() error {
13481347
errs:=make(chanerror)
13491348
select {
13501349
case<-f.ctx.Done():
1351-
f.t.Error("timed out waiting to send close call")
1352-
returnf.ctx.Err()
1350+
returntimeoutOnFakeErr
13531351
casef.close<-errs:
13541352
// OK
13551353
}
13561354
select {
13571355
case<-f.ctx.Done():
1358-
f.t.Error("timed out waiting for close call response")
1359-
returnf.ctx.Err()
1356+
returntimeoutOnFakeErr
13601357
caseerr:=<-errs:
13611358
returnerr
13621359
}
@@ -1372,15 +1369,13 @@ func (f *fakeWorkspaceUpdateClient) Recv() (*proto.WorkspaceUpdate, error) {
13721369
}
13731370
select {
13741371
case<-f.ctx.Done():
1375-
f.t.Error("timed out waiting to send Recv() call")
1376-
returnnil,f.ctx.Err()
1372+
returnnil,timeoutOnFakeErr
13771373
casef.recv<-call:
13781374
// OK
13791375
}
13801376
select {
13811377
case<-f.ctx.Done():
1382-
f.t.Error("timed out waiting for Recv() call response")
1383-
returnnil,f.ctx.Err()
1378+
returnnil,timeoutOnFakeErr
13841379
caseerr:=<-errs:
13851380
returnnil,err
13861381
caseresp:=<-resps:
@@ -1440,28 +1435,26 @@ func (f *fakeDNSSetter) SetDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error {
14401435
}
14411436
select {
14421437
case<-f.ctx.Done():
1443-
f.t.Error("timed out waiting to send SetDNSHosts() call")
1444-
returnf.ctx.Err()
1438+
returntimeoutOnFakeErr
14451439
casef.calls<-call:
14461440
// OK
14471441
}
14481442
select {
14491443
case<-f.ctx.Done():
1450-
f.t.Error("timed out waiting for SetDNSHosts() call response")
1451-
returnf.ctx.Err()
1444+
returntimeoutOnFakeErr
14521445
caseerr:=<-errs:
14531446
returnerr
14541447
}
14551448
}
14561449

14571450
funcsetupConnectedAllWorkspaceUpdatesController(
1458-
ctx context.Context,t testing.TB,logger slog.Logger,dnsSettertailnet.DNSHostsSetter,
1451+
ctx context.Context,t testing.TB,logger slog.Logger,opts...tailnet.TunnelAllOption,
14591452
) (
14601453
*fakeCoordinatorClient,*fakeWorkspaceUpdateClient,
14611454
) {
14621455
fConn:=&fakeCoordinatee{}
14631456
tsc:=tailnet.NewTunnelSrcCoordController(logger,fConn)
1464-
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,dnsSetter)
1457+
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,opts...)
14651458

14661459
// connect up a coordinator client, to track adding and removing tunnels
14671460
coordC:=newFakeCoordinatorClient(ctx,t)
@@ -1496,7 +1489,8 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
14961489
logger:=testutil.Logger(t)
14971490

14981491
fDNS:=newFakeDNSSetter(ctx,t)
1499-
coordC,updateC:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,fDNS)
1492+
coordC,updateC:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,
1493+
tailnet.WithDNS(fDNS,"testy"))
15001494

15011495
// Initial update contains 2 workspaces with 1 & 2 agents, respectively
15021496
w1ID:=testUUID(1)
@@ -1532,9 +1526,13 @@ func TestTunnelAllWorkspaceUpdatesController_Initial(t *testing.T) {
15321526

15331527
// Also triggers setting DNS hosts
15341528
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
1535-
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1536-
"w2a1.w2.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0201::")},
1537-
"w2a2.w2.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0202::")},
1529+
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1530+
"w2a1.w2.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0201::")},
1531+
"w2a2.w2.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0202::")},
1532+
"w1a1.w1.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1533+
"w2a1.w2.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0201::")},
1534+
"w2a2.w2.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0202::")},
1535+
"w1.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
15381536
}
15391537
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
15401538
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1547,7 +1545,8 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
15471545
logger:=testutil.Logger(t)
15481546

15491547
fDNS:=newFakeDNSSetter(ctx,t)
1550-
coordC,updateC:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,fDNS)
1548+
coordC,updateC:=setupConnectedAllWorkspaceUpdatesController(ctx,t,logger,
1549+
tailnet.WithDNS(fDNS,"testy"))
15511550

15521551
w1ID:=testUUID(1)
15531552
w1a1ID:=testUUID(1,1)
@@ -1571,7 +1570,9 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
15711570

15721571
// DNS for w1a1
15731572
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
1574-
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1573+
"w1a1.w1.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1574+
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1575+
"w1.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
15751576
}
15761577
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
15771578
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1601,7 +1602,9 @@ func TestTunnelAllWorkspaceUpdatesController_DeleteAgent(t *testing.T) {
16011602

16021603
// DNS contains only w1a2
16031604
expectedDNS=map[dnsname.FQDN][]netip.Addr{
1604-
"w1a2.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0102::")},
1605+
"w1a2.w1.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0102::")},
1606+
"w1a2.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0102::")},
1607+
"w1.coder.": {netip.MustParseAddr("fd60:627a:a42b:0102::")},
16051608
}
16061609
dnsCall=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
16071610
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1619,7 +1622,9 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
16191622
fDNS:=newFakeDNSSetter(ctx,t)
16201623
fConn:=&fakeCoordinatee{}
16211624
tsc:=tailnet.NewTunnelSrcCoordController(logger,fConn)
1622-
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,fDNS)
1625+
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,
1626+
tailnet.WithDNS(fDNS,"testy"),
1627+
)
16231628

16241629
updateC:=newFakeWorkspaceUpdateClient(ctx,t)
16251630
updateCW:=uut.New(updateC)
@@ -1639,7 +1644,9 @@ func TestTunnelAllWorkspaceUpdatesController_DNSError(t *testing.T) {
16391644

16401645
// DNS for w1a1
16411646
expectedDNS:=map[dnsname.FQDN][]netip.Addr{
1642-
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1647+
"w1a1.w1.me.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1648+
"w1a1.w1.testy.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
1649+
"w1.coder.": {netip.MustParseAddr("fd60:627a:a42b:0101::")},
16431650
}
16441651
dnsCall:=testutil.RequireRecvCtx(ctx,t,fDNS.calls)
16451652
require.Equal(t,expectedDNS,dnsCall.hosts)
@@ -1746,7 +1753,7 @@ func TestTunnelAllWorkspaceUpdatesController_HandleErrors(t *testing.T) {
17461753

17471754
fConn:=&fakeCoordinatee{}
17481755
tsc:=tailnet.NewTunnelSrcCoordController(logger,fConn)
1749-
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc,nil)
1756+
uut:=tailnet.NewTunnelAllWorkspaceUpdatesController(logger,tsc)
17501757
updateC:=newFakeWorkspaceUpdateClient(ctx,t)
17511758
updateCW:=uut.New(updateC)
17521759

@@ -1780,18 +1787,16 @@ func (f fakeWorkspaceUpdatesController) New(client tailnet.WorkspaceUpdatesClien
17801787
}
17811788
select {
17821789
case<-f.ctx.Done():
1783-
f.t.Error("timed out waiting to send New call")
17841790
cw:=newFakeCloserWaiter()
1785-
cw.errCh<-f.ctx.Err()
1791+
cw.errCh<-timeoutOnFakeErr
17861792
returncw
17871793
casef.calls<-call:
17881794
// OK
17891795
}
17901796
select {
17911797
case<-f.ctx.Done():
1792-
f.t.Error("timed out waiting to get New call response")
17931798
cw:=newFakeCloserWaiter()
1794-
cw.errCh<-f.ctx.Err()
1799+
cw.errCh<-timeoutOnFakeErr
17951800
returncw
17961801
caseresp:=<-resps:
17971802
returnresp

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp