client/local, ipn/localapi, all: add CertDomains and DNSConfig accessors
Add two narrow LocalAPI accessors so callers don't have to subscribe to
the IPN bus and pull a full *netmap.NetworkMap just to read DNS-shaped
fields:
- GET /localapi/v0/cert-domains returns DNS.CertDomains.
- GET /localapi/v0/dns-config returns the full tailcfg.DNSConfig.
Migrate in-tree callers off the netmap-on-the-bus pattern:
- kube/certs.waitForCertDomain still wakes on the IPN bus but now
queries CertDomains via LocalClient.CertDomains rather than
reading n.NetMap.DNS.CertDomains. The kube LocalClient interface
and FakeLocalClient gain a CertDomains method.
- cmd/tailscale dns status calls LocalClient.DNSConfig directly
instead of opening a NotifyInitialNetMap watcher.
- cmd/tailscale configure kubeconfig switches from a netmap watcher
+ serviceDNSRecordFromNetMap to LocalClient.DNSConfig +
serviceDNSRecordFromDNSConfig.
This is part of a series moving callers away from depending on the
netmap traveling on the IPN bus, so the bus payload can shrink in a
later change.
Updates #12542
Change-Id: Ie10204e141d085fbac183b4cfe497226b670ad6c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
822299642b
commit
9f343fdc0c
+11
-2
@@ -173,6 +173,12 @@ func (cm *CertManager) runCertLoop(ctx context.Context, domain string) {
|
||||
|
||||
// waitForCertDomain ensures the requested domain is in the list of allowed
|
||||
// domains before issuing the cert for the first time.
|
||||
// It uses the IPN bus only as a wake-up trigger and queries the current cert
|
||||
// domains explicitly via [LocalClient.CertDomains].
|
||||
//
|
||||
// TODO(bradfitz): once Notify.SelfChange lands upstream, switch this to
|
||||
// watch for SelfChange events instead of NotifyInitialNetMap, and drop the
|
||||
// netmap dependency on the bus entirely.
|
||||
func (cm *CertManager) waitForCertDomain(ctx context.Context, domain string) error {
|
||||
w, err := cm.lc.WatchIPNBus(ctx, ipn.NotifyInitialNetMap)
|
||||
if err != nil {
|
||||
@@ -188,8 +194,11 @@ func (cm *CertManager) waitForCertDomain(ctx context.Context, domain string) err
|
||||
if n.NetMap == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if slices.Contains(n.NetMap.DNS.CertDomains, domain) {
|
||||
domains, err := cm.lc.CertDomains(ctx)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if slices.Contains(domains, domain) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
+10
-11
@@ -201,18 +201,12 @@ func TestEnsureCertLoops(t *testing.T) {
|
||||
|
||||
notifyChan := make(chan ipn.Notify)
|
||||
go func() {
|
||||
// Drive waitForCertDomain by sending notifications
|
||||
// with empty netmaps as wake-up triggers; the cert
|
||||
// manager queries CertDomains via the local
|
||||
// client and not by reading the bus payload.
|
||||
for {
|
||||
notifyChan <- ipn.Notify{
|
||||
NetMap: &netmap.NetworkMap{
|
||||
DNS: tailcfg.DNSConfig{
|
||||
CertDomains: []string{
|
||||
"my-app.tailnetxyz.ts.net",
|
||||
"my-other-app.tailnetxyz.ts.net",
|
||||
"my-apiserver.tailnetxyz.ts.net",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
notifyChan <- ipn.Notify{NetMap: &netmap.NetworkMap{}}
|
||||
}
|
||||
}()
|
||||
cm := &CertManager{
|
||||
@@ -220,6 +214,11 @@ func TestEnsureCertLoops(t *testing.T) {
|
||||
FakeIPNBusWatcher: localclient.FakeIPNBusWatcher{
|
||||
NotifyChan: notifyChan,
|
||||
},
|
||||
CertDomainsResult: []string{
|
||||
"my-app.tailnetxyz.ts.net",
|
||||
"my-other-app.tailnetxyz.ts.net",
|
||||
"my-apiserver.tailnetxyz.ts.net",
|
||||
},
|
||||
},
|
||||
logf: log.Printf,
|
||||
certLoops: make(map[string]context.CancelFunc),
|
||||
|
||||
@@ -12,9 +12,10 @@ import (
|
||||
|
||||
type FakeLocalClient struct {
|
||||
FakeIPNBusWatcher
|
||||
SetServeCalled bool
|
||||
EditPrefsCalls []*ipn.MaskedPrefs
|
||||
GetPrefsResult *ipn.Prefs
|
||||
SetServeCalled bool
|
||||
EditPrefsCalls []*ipn.MaskedPrefs
|
||||
GetPrefsResult *ipn.Prefs
|
||||
CertDomainsResult []string
|
||||
}
|
||||
|
||||
func (m *FakeLocalClient) SetServeConfig(ctx context.Context, cfg *ipn.ServeConfig) error {
|
||||
@@ -45,6 +46,10 @@ func (f *FakeLocalClient) CertPair(ctx context.Context, domain string) ([]byte,
|
||||
return nil, nil, fmt.Errorf("CertPair not implemented")
|
||||
}
|
||||
|
||||
func (f *FakeLocalClient) CertDomains(ctx context.Context) ([]string, error) {
|
||||
return f.CertDomainsResult, nil
|
||||
}
|
||||
|
||||
type FakeIPNBusWatcher struct {
|
||||
NotifyChan chan ipn.Notify
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ type LocalClient interface {
|
||||
WatchIPNBus(ctx context.Context, mask ipn.NotifyWatchOpt) (IPNBusWatcher, error)
|
||||
SetServeConfig(context.Context, *ipn.ServeConfig) error
|
||||
EditPrefs(ctx context.Context, mp *ipn.MaskedPrefs) (*ipn.Prefs, error)
|
||||
CertDomains(ctx context.Context) ([]string, error)
|
||||
CertIssuer
|
||||
}
|
||||
|
||||
@@ -57,3 +58,7 @@ func (lc *localClient) WatchIPNBus(ctx context.Context, mask ipn.NotifyWatchOpt)
|
||||
func (lc *localClient) CertPair(ctx context.Context, domain string) ([]byte, []byte, error) {
|
||||
return lc.lc.CertPair(ctx, domain)
|
||||
}
|
||||
|
||||
func (lc *localClient) CertDomains(ctx context.Context) ([]string, error) {
|
||||
return lc.lc.CertDomains(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user