ipn/ipn{ext,local}: allow extension lookup by name or type

In this PR, we add two methods to facilitate extension lookup by both extensions,
and non-extensions (e.g., PeerAPI or LocalAPI handlers):
 - FindExtensionByName returns an extension with the specified name.
   It can then be type asserted to a given type.
 - FindMatchingExtension is like errors.As, but for extensions.
   It returns the first extension that matches the target type (either a specific extension
   or an interface).

Updates tailscale/corp#27645
Updates tailscale/corp#27502

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2025-04-11 10:09:03 -05:00
committed by Nick Khyl
parent 1e290867bd
commit f28c8d0ec0
4 changed files with 184 additions and 0 deletions
+16
View File
@@ -589,6 +589,22 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
return b, nil
}
// FindExtensionByName returns an active extension with the given name,
// or nil if no such extension exists.
func (b *LocalBackend) FindExtensionByName(name string) any {
return b.extHost.Extensions().FindExtensionByName(name)
}
// FindMatchingExtension finds the first active extension that matches target,
// and if one is found, sets target to that extension and returns true.
// Otherwise, it returns false.
//
// It panics if target is not a non-nil pointer to either a type
// that implements [ipnext.Extension], or to any interface type.
func (b *LocalBackend) FindMatchingExtension(target any) bool {
return b.extHost.Extensions().FindMatchingExtension(target)
}
type componentLogState struct {
until time.Time
timer tstime.TimerController // if non-nil, the AfterFunc to disable it