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

Commit5b5bc1d

Browse files
authored
feat: Add local configuration option for DERP mapping (#3996)
This allows entirely airgapped geodistributed deployments of Coder!
1 parent6e20f9c commit5b5bc1d

File tree

5 files changed

+81
-30
lines changed

5 files changed

+81
-30
lines changed

‎cli/server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func Server(newAPI func(*coderd.Options) *coderd.API) *cobra.Command {
8181
derpServerRegionNamestring
8282
derpServerSTUNAddrs []string
8383
derpConfigURLstring
84+
derpConfigPathstring
8485
promEnabledbool
8586
promAddressstring
8687
pprofEnabledbool
@@ -345,7 +346,7 @@ func Server(newAPI func(*coderd.Options) *coderd.API) *cobra.Command {
345346
if!derpServerEnabled {
346347
defaultRegion=nil
347348
}
348-
derpMap,err:=tailnet.NewDERPMap(ctx,defaultRegion,derpServerSTUNAddrs,derpConfigURL)
349+
derpMap,err:=tailnet.NewDERPMap(ctx,defaultRegion,derpServerSTUNAddrs,derpConfigURL,derpConfigPath)
349350
iferr!=nil {
350351
returnxerrors.Errorf("create derp map: %w",err)
351352
}
@@ -753,6 +754,8 @@ func Server(newAPI func(*coderd.Options) *coderd.API) *cobra.Command {
753754
cliflag.StringVarP(root.Flags(),&address,"address","a","CODER_ADDRESS","127.0.0.1:3000","The address to serve the API and dashboard.")
754755
cliflag.StringVarP(root.Flags(),&derpConfigURL,"derp-config-url","","CODER_DERP_CONFIG_URL","",
755756
"Specifies a URL to periodically fetch a DERP map. See: https://tailscale.com/kb/1118/custom-derp-servers/")
757+
cliflag.StringVarP(root.Flags(),&derpConfigPath,"derp-config-path","","CODER_DERP_CONFIG_PATH","",
758+
"Specifies a path to read a DERP map from. See: https://tailscale.com/kb/1118/custom-derp-servers/")
756759
cliflag.BoolVarP(root.Flags(),&derpServerEnabled,"derp-server-enable","","CODER_DERP_SERVER_ENABLE",true,"Specifies whether to enable or disable the embedded DERP server.")
757760
cliflag.IntVarP(root.Flags(),&derpServerRegionID,"derp-server-region-id","","CODER_DERP_SERVER_REGION_ID",999,"Specifies the region ID to use for the embedded DERP server.")
758761
cliflag.StringVarP(root.Flags(),&derpServerRegionCode,"derp-server-region-code","","CODER_DERP_SERVER_REGION_CODE","coder","Specifies the region code that is displayed in the Coder UI for the embedded DERP server.")
@@ -763,6 +766,7 @@ func Server(newAPI func(*coderd.Options) *coderd.API) *cobra.Command {
763766

764767
// Mark hidden while this feature is in testing!
765768
_=root.Flags().MarkHidden("derp-config-url")
769+
_=root.Flags().MarkHidden("derp-config-path")
766770
_=root.Flags().MarkHidden("derp-server-enable")
767771
_=root.Flags().MarkHidden("derp-server-region-id")
768772
_=root.Flags().MarkHidden("derp-server-region-code")

‎cli/speedtest.go

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
tsspeedtest"tailscale.com/net/speedtest"
1212

1313
"cdr.dev/slog"
14+
"cdr.dev/slog/sloggers/sloghuman"
1415
"github.com/coder/coder/agent"
1516
"github.com/coder/coder/cli/cliflag"
1617
"github.com/coder/coder/cli/cliui"
@@ -51,36 +52,43 @@ func speedtest() *cobra.Command {
5152
iferr!=nil {
5253
returnxerrors.Errorf("await agent: %w",err)
5354
}
54-
conn,err:=client.DialWorkspaceAgentTailnet(ctx, slog.Logger{},workspaceAgent.ID)
55+
logger:=slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
56+
ifcliflag.IsSetBool(cmd,varVerbose) {
57+
logger=logger.Leveled(slog.LevelDebug)
58+
}
59+
conn,err:=client.DialWorkspaceAgentTailnet(ctx,logger,workspaceAgent.ID)
5560
iferr!=nil {
5661
returnerr
5762
}
5863
deferconn.Close()
59-
ifdirect {
60-
ticker:=time.NewTicker(time.Second)
61-
deferticker.Stop()
62-
for {
63-
select {
64-
case<-ctx.Done():
65-
returnctx.Err()
66-
case<-ticker.C:
67-
}
68-
dur,err:=conn.Ping()
69-
iferr!=nil {
70-
continue
71-
}
72-
tc,_:=conn.(*agent.TailnetConn)
73-
status:=tc.Status()
74-
iflen(status.Peers())!=1 {
75-
continue
76-
}
77-
peer:=status.Peer[status.Peers()[0]]
78-
ifpeer.CurAddr=="" {
79-
cmd.Printf("Waiting for a direct connection... (%dms via %s)\n",dur.Milliseconds(),peer.Relay)
80-
continue
81-
}
82-
break
64+
ticker:=time.NewTicker(time.Second)
65+
deferticker.Stop()
66+
for {
67+
select {
68+
case<-ctx.Done():
69+
returnctx.Err()
70+
case<-ticker.C:
71+
}
72+
dur,err:=conn.Ping()
73+
iferr!=nil {
74+
continue
75+
}
76+
tc,_:=conn.(*agent.TailnetConn)
77+
status:=tc.Status()
78+
iflen(status.Peers())!=1 {
79+
continue
80+
}
81+
peer:=status.Peer[status.Peers()[0]]
82+
ifpeer.CurAddr==""&&direct {
83+
cmd.Printf("Waiting for a direct connection... (%dms via %s)\n",dur.Milliseconds(),peer.Relay)
84+
continue
85+
}
86+
via:=peer.Relay
87+
ifvia=="" {
88+
via="direct"
8389
}
90+
cmd.Printf("%dms via %s\n",dur.Milliseconds(),via)
91+
break
8492
}
8593
dir:=tsspeedtest.Download
8694
ifreverse {

‎tailnet/conn.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ func (c *Conn) SetNodeCallback(callback func(node *Node)) {
268268
case<-c.closed:
269269
return
270270
casenode:=<-queue:
271+
c.logger.Debug(context.Background(),"send node callback",slog.F("node",node))
271272
callback(node)
272273
}
273274
}
@@ -299,6 +300,8 @@ func (c *Conn) SetNodeCallback(callback func(node *Node)) {
299300
func (c*Conn)SetDERPMap(derpMap*tailcfg.DERPMap) {
300301
c.mutex.Lock()
301302
deferc.mutex.Unlock()
303+
c.netMap.DERPMap=derpMap
304+
c.logger.Debug(context.Background(),"updating derp map",slog.F("derp_map",derpMap))
302305
c.wireguardEngine.SetDERPMap(derpMap)
303306
}
304307

@@ -340,6 +343,9 @@ func (c *Conn) UpdateNodes(nodes []*Node) error {
340343
existingNode,ok:=peerMap[node.ID]
341344
ifok {
342345
peerNode.Created=existingNode.Created
346+
c.logger.Debug(context.Background(),"updating peer",slog.F("peer",peerNode))
347+
}else {
348+
c.logger.Debug(context.Background(),"adding peer",slog.F("peer",peerNode))
343349
}
344350
peerMap[node.ID]=peerNode
345351
}

‎tailnet/derpmap.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"net"
88
"net/http"
9+
"os"
910
"strconv"
1011

1112
"golang.org/x/xerrors"
@@ -14,7 +15,10 @@ import (
1415

1516
// NewDERPMap constructs a DERPMap from a set of STUN addresses and optionally a remote
1617
// URL to fetch a mapping from e.g. https://controlplane.tailscale.com/derpmap/default.
17-
funcNewDERPMap(ctx context.Context,region*tailcfg.DERPRegion,stunAddrs []string,remoteURLstring) (*tailcfg.DERPMap,error) {
18+
funcNewDERPMap(ctx context.Context,region*tailcfg.DERPRegion,stunAddrs []string,remoteURL,localPathstring) (*tailcfg.DERPMap,error) {
19+
ifremoteURL!=""&&localPath!="" {
20+
returnnil,xerrors.New("a remote URL or local path must be specified, not both")
21+
}
1822
ifregion!=nil {
1923
forindex,stunAddr:=rangestunAddrs {
2024
host,rawPort,err:=net.SplitHostPort(stunAddr)
@@ -53,6 +57,16 @@ func NewDERPMap(ctx context.Context, region *tailcfg.DERPRegion, stunAddrs []str
5357
returnnil,xerrors.Errorf("fetch derpmap: %w",err)
5458
}
5559
}
60+
iflocalPath!="" {
61+
content,err:=os.ReadFile(localPath)
62+
iferr!=nil {
63+
returnnil,xerrors.Errorf("read derpmap from %q: %w",localPath,err)
64+
}
65+
err=json.Unmarshal(content,&derpMap)
66+
iferr!=nil {
67+
returnnil,xerrors.Errorf("unmarshal derpmap: %w",err)
68+
}
69+
}
5670
ifregion!=nil {
5771
_,conflicts:=derpMap.Regions[region.RegionID]
5872
ifconflicts {

‎tailnet/derpmap_test.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"net/http"
77
"net/http/httptest"
8+
"os"
9+
"path/filepath"
810
"testing"
911

1012
"github.com/stretchr/testify/require"
@@ -20,7 +22,7 @@ func TestNewDERPMap(t *testing.T) {
2022
derpMap,err:=tailnet.NewDERPMap(context.Background(),&tailcfg.DERPRegion{
2123
RegionID:1,
2224
Nodes: []*tailcfg.DERPNode{{}},
23-
}, []string{"stun.google.com:2345"},"")
25+
}, []string{"stun.google.com:2345"},"","")
2426
require.NoError(t,err)
2527
require.Len(t,derpMap.Regions[1].Nodes,2)
2628
})
@@ -37,7 +39,7 @@ func TestNewDERPMap(t *testing.T) {
3739
t.Cleanup(server.Close)
3840
derpMap,err:=tailnet.NewDERPMap(context.Background(),&tailcfg.DERPRegion{
3941
RegionID:2,
40-
}, []string{},server.URL)
42+
}, []string{},server.URL,"")
4143
require.NoError(t,err)
4244
require.Len(t,derpMap.Regions,2)
4345
})
@@ -54,7 +56,24 @@ func TestNewDERPMap(t *testing.T) {
5456
t.Cleanup(server.Close)
5557
_,err:=tailnet.NewDERPMap(context.Background(),&tailcfg.DERPRegion{
5658
RegionID:1,
57-
}, []string{},server.URL)
59+
}, []string{},server.URL,"")
5860
require.Error(t,err)
5961
})
62+
t.Run("LocalPath",func(t*testing.T) {
63+
t.Parallel()
64+
localPath:=filepath.Join(t.TempDir(),"derp.json")
65+
content,err:=json.Marshal(&tailcfg.DERPMap{
66+
Regions:map[int]*tailcfg.DERPRegion{
67+
1: {},
68+
},
69+
})
70+
require.NoError(t,err)
71+
err=os.WriteFile(localPath,content,0600)
72+
require.NoError(t,err)
73+
derpMap,err:=tailnet.NewDERPMap(context.Background(),&tailcfg.DERPRegion{
74+
RegionID:2,
75+
}, []string{},"",localPath)
76+
require.NoError(t,err)
77+
require.Len(t,derpMap.Regions,2)
78+
})
6079
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp