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

feat: set DNS hostnames in workspace updates controller#15507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
spikecurtis merged 1 commit intomainfromspike/14730-set-dns
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletionstailnet/configmaps.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -277,16 +277,6 @@ func (c *configMaps) setAddresses(ips []netip.Prefix) {
c.Broadcast()
}

func (c *configMaps) addHosts(hosts map[dnsname.FQDN][]netip.Addr) {
c.L.Lock()
defer c.L.Unlock()
for name, addrs := range hosts {
c.hosts[name] = slices.Clone(addrs)
}
c.netmapDirty = true
c.Broadcast()
}

func (c *configMaps) setHosts(hosts map[dnsname.FQDN][]netip.Addr) {
c.L.Lock()
defer c.L.Unlock()
Expand All@@ -298,16 +288,6 @@ func (c *configMaps) setHosts(hosts map[dnsname.FQDN][]netip.Addr) {
c.Broadcast()
}

func (c *configMaps) removeHosts(names []dnsname.FQDN) {
c.L.Lock()
defer c.L.Unlock()
for _, name := range names {
delete(c.hosts, name)
}
c.netmapDirty = true
c.Broadcast()
}

// setBlockEndpoints sets whether we should block configuring endpoints we learn
// from peers. It triggers a configuration of the engine if the value changes.
// nolint: revive
Expand Down
39 changes: 4 additions & 35 deletionstailnet/configmaps_internal_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,6 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/dns"
"tailscale.com/tailcfg"
Expand DownExpand Up@@ -1177,8 +1176,8 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
addr3 := CoderServicePrefix.AddrFromUUID(uuid.New())
addr4 := CoderServicePrefix.AddrFromUUID(uuid.New())

// WHEN: weadd two hosts
uut.addHosts(map[dnsname.FQDN][]netip.Addr{
// WHEN: weset two hosts
uut.setHosts(map[dnsname.FQDN][]netip.Addr{
"agent.myws.me.coder.": {
addr1,
},
Expand DownExpand Up@@ -1207,36 +1206,6 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
OnlyIPv6: true,
})

// WHEN: we add a new host
newHost := map[dnsname.FQDN][]netip.Addr{
"agent2.myws.me.coder.": {
addr4,
},
}
uut.addHosts(newHost)

// THEN: the engine is reconfigured with both the old and new hosts
_ = testutil.RequireRecvCtx(ctx, t, fEng.setNetworkMap)
req = testutil.RequireRecvCtx(ctx, t, fEng.reconfig)
require.Equal(t, req.dnsCfg, &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
CoderDNSSuffix: nil,
},
Hosts: map[dnsname.FQDN][]netip.Addr{
"agent.myws.me.coder.": {
addr1,
},
"dev.main.me.coder.": {
addr2,
addr3,
},
"agent2.myws.me.coder.": {
addr4,
},
},
OnlyIPv6: true,
})

// WHEN: We replace the hosts with a new set
uut.setHosts(map[dnsname.FQDN][]netip.Addr{
"newagent.myws.me.coder.": {
Expand DownExpand Up@@ -1265,8 +1234,8 @@ func TestConfigMaps_addRemoveHosts(t *testing.T) {
OnlyIPv6: true,
})

// WHEN: we remove all the hosts, and a bad host
uut.removeHosts(append(maps.Keys(req.dnsCfg.Hosts), "badhostname"))
// WHEN: we remove all the hosts
uut.setHosts(map[dnsname.FQDN][]netip.Addr{})
_ = testutil.RequireRecvCtx(ctx, t, fEng.setNetworkMap)
req = testutil.RequireRecvCtx(ctx, t, fEng.reconfig)

Expand Down
16 changes: 0 additions & 16 deletionstailnet/conn.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -451,22 +451,6 @@ func (c *Conn) SetAddresses(ips []netip.Prefix) error {
return nil
}

func (c *Conn) AddDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error {
if c.dnsConfigurator == nil {
return xerrors.New("no DNSConfigurator set")
}
c.configMaps.addHosts(hosts)
return nil
}

func (c *Conn) RemoveDNSHosts(names []dnsname.FQDN) error {
if c.dnsConfigurator == nil {
return xerrors.New("no DNSConfigurator set")
}
c.configMaps.removeHosts(names)
return nil
}

// SetDNSHosts replaces the map of DNS hosts for the connection.
func (c *Conn) SetDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error {
if c.dnsConfigurator == nil {
Expand Down
87 changes: 72 additions & 15 deletionstailnet/controllers.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ import (
"io"
"maps"
"math"
"net/netip"
"strings"
"sync"
"time"
Expand All@@ -15,6 +16,7 @@ import (
"storj.io/drpc"
"storj.io/drpc/drpcerr"
"tailscale.com/tailcfg"
"tailscale.com/util/dnsname"

"cdr.dev/slog"
"github.com/coder/coder/v2/codersdk"
Expand DownExpand Up@@ -104,6 +106,12 @@ type WorkspaceUpdatesController interface {
New(WorkspaceUpdatesClient) CloserWaiter
}

// DNSHostsSetter is something that you can set a mapping of DNS names to IPs on. It's the subset
// of the tailnet.Conn that we use to configure DNS records.
type DNSHostsSetter interface {
SetDNSHosts(hosts map[dnsname.FQDN][]netip.Addr) error
}

// ControlProtocolClients represents an abstract interface to the tailnet control plane via a set
// of protocol clients. The Closer should close all the clients (e.g. by closing the underlying
// connection).
Expand DownExpand Up@@ -835,8 +843,9 @@ func (r *basicResumeTokenRefresher) refresh() {
}

type tunnelAllWorkspaceUpdatesController struct {
coordCtrl *TunnelSrcCoordController
logger slog.Logger
coordCtrl *TunnelSrcCoordController
dnsHostSetter DNSHostsSetter
logger slog.Logger
}

type workspace struct {
Expand All@@ -845,30 +854,48 @@ type workspace struct {
agents map[uuid.UUID]agent
}

// addAllDNSNames adds names for all of its agents to the given map of names
func (w workspace) addAllDNSNames(names map[dnsname.FQDN][]netip.Addr) error {
for _, a := range w.agents {
// TODO: technically, DNS labels cannot start with numbers, but the rules are often not
// strictly enforced.
// TODO: support <agent>.<workspace>.<username>.coder
fqdn, err := dnsname.ToFQDN(fmt.Sprintf("%s.%s.me.coder.", a.name, w.name))
if err != nil {
return err
}
names[fqdn] = []netip.Addr{CoderServicePrefix.AddrFromUUID(a.id)}
}
// TODO: Possibly support <workspace>.coder. alias if there is only one agent
return nil
}

type agent struct {
id uuid.UUID
name string
}

func (t *tunnelAllWorkspaceUpdatesController) New(client WorkspaceUpdatesClient) CloserWaiter {
updater := &tunnelUpdater{
client: client,
errChan: make(chan error, 1),
logger: t.logger,
coordCtrl: t.coordCtrl,
recvLoopDone: make(chan struct{}),
workspaces: make(map[uuid.UUID]*workspace),
client: client,
errChan: make(chan error, 1),
logger: t.logger,
coordCtrl: t.coordCtrl,
dnsHostsSetter: t.dnsHostSetter,
recvLoopDone: make(chan struct{}),
workspaces: make(map[uuid.UUID]*workspace),
}
go updater.recvLoop()
return updater
}

type tunnelUpdater struct {
errChan chan error
logger slog.Logger
client WorkspaceUpdatesClient
coordCtrl *TunnelSrcCoordController
recvLoopDone chan struct{}
errChan chan error
logger slog.Logger
client WorkspaceUpdatesClient
coordCtrl *TunnelSrcCoordController
dnsHostsSetter DNSHostsSetter
recvLoopDone chan struct{}

// don't need the mutex since only manipulated by the recvLoop
workspaces map[uuid.UUID]*workspace
Expand DownExpand Up@@ -991,6 +1018,16 @@ func (t *tunnelUpdater) handleUpdate(update *proto.WorkspaceUpdate) error {
}
allAgents := t.allAgentIDs()
t.coordCtrl.SyncDestinations(allAgents)
if t.dnsHostsSetter != nil {
t.logger.Debug(context.Background(), "updating dns hosts")
dnsNames := t.allDNSNames()
err := t.dnsHostsSetter.SetDNSHosts(dnsNames)
if err != nil {
return xerrors.Errorf("failed to set DNS hosts: %w", err)
}
} else {
t.logger.Debug(context.Background(), "skipping setting DNS names because we have no setter")
}
return nil
}

Expand DownExpand Up@@ -1035,10 +1072,30 @@ func (t *tunnelUpdater) allAgentIDs() []uuid.UUID {
return out
}

func (t *tunnelUpdater) allDNSNames() map[dnsname.FQDN][]netip.Addr {
names := make(map[dnsname.FQDN][]netip.Addr)
for _, w := range t.workspaces {
err := w.addAllDNSNames(names)
if err != nil {
// This should never happen in production, because converting the FQDN only fails
// if names are too long, and we put strict length limits on agent, workspace, and user
// names.
t.logger.Critical(context.Background(),
"failed to include DNS name(s)",
slog.F("workspace_id", w.id),
slog.Error(err))
}
}
return names
}

// NewTunnelAllWorkspaceUpdatesController creates a WorkspaceUpdatesController that creates tunnels
// (via the TunnelSrcCoordController) to all agents received over the WorkspaceUpdates RPC. If a
// DNSHostSetter is provided, it also programs DNS hosts based on the agent and workspace names.
func NewTunnelAllWorkspaceUpdatesController(
logger slog.Logger, c *TunnelSrcCoordController,
logger slog.Logger, c *TunnelSrcCoordController, d DNSHostsSetter,
) WorkspaceUpdatesController {
return &tunnelAllWorkspaceUpdatesController{logger: logger, coordCtrl: c}
return &tunnelAllWorkspaceUpdatesController{logger: logger, coordCtrl: c, dnsHostSetter: d}
}

// NewController creates a new Controller without running it
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp