diff options
| author | Brad Fitzpatrick <bradfitz@tailscale.com> | 2025-01-26 18:23:38 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <brad@danga.com> | 2025-01-26 18:49:11 +0000 |
| commit | e701fde6b389a4a69b4d33aace8969530b25de8d (patch) | |
| tree | c61e69301d643816bb7c794ff1827b6988345099 /control/controlknobs/controlknobs.go | |
| parent | 66b2e9fd07f2c635b809aa82d657fd82de3f9323 (diff) | |
| download | tailscale-e701fde6b389a4a69b4d33aace8969530b25de8d.tar.xz tailscale-e701fde6b389a4a69b4d33aace8969530b25de8d.zip | |
control/controlknobs: make Knobs.AsDebugJSON automatic, not require maintenance
The AsDebugJSON method (used only for a LocalAPI debug call) always
needed to be updated whenever a new controlknob was added. We had a
test for it, which was nice, but it was a tedious step we don't need
to do. Use reflect instead.
Updates #14788
Change-Id: If59cd776920f3ce7c748f86ed2eddd9323039a0b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'control/controlknobs/controlknobs.go')
| -rw-r--r-- | control/controlknobs/controlknobs.go | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/control/controlknobs/controlknobs.go b/control/controlknobs/controlknobs.go index c7933be5a..a86f0af53 100644 --- a/control/controlknobs/controlknobs.go +++ b/control/controlknobs/controlknobs.go @@ -6,6 +6,8 @@ package controlknobs import ( + "fmt" + "reflect" "sync/atomic" "tailscale.com/syncs" @@ -174,26 +176,19 @@ func (k *Knobs) AsDebugJSON() map[string]any { if k == nil { return nil } - return map[string]any{ - "DisableUPnP": k.DisableUPnP.Load(), - "KeepFullWGConfig": k.KeepFullWGConfig.Load(), - "RandomizeClientPort": k.RandomizeClientPort.Load(), - "OneCGNAT": k.OneCGNAT.Load(), - "ForceBackgroundSTUN": k.ForceBackgroundSTUN.Load(), - "DisableDeltaUpdates": k.DisableDeltaUpdates.Load(), - "PeerMTUEnable": k.PeerMTUEnable.Load(), - "DisableDNSForwarderTCPRetries": k.DisableDNSForwarderTCPRetries.Load(), - "SilentDisco": k.SilentDisco.Load(), - "LinuxForceIPTables": k.LinuxForceIPTables.Load(), - "LinuxForceNfTables": k.LinuxForceNfTables.Load(), - "SeamlessKeyRenewal": k.SeamlessKeyRenewal.Load(), - "ProbeUDPLifetime": k.ProbeUDPLifetime.Load(), - "AppCStoreRoutes": k.AppCStoreRoutes.Load(), - "UserDialUseRoutes": k.UserDialUseRoutes.Load(), - "DisableSplitDNSWhenNoCustomResolvers": k.DisableSplitDNSWhenNoCustomResolvers.Load(), - "DisableLocalDNSOverrideViaNRPT": k.DisableLocalDNSOverrideViaNRPT.Load(), - "DisableCryptorouting": k.DisableCryptorouting.Load(), - "DisableCaptivePortalDetection": k.DisableCaptivePortalDetection.Load(), - "DisableSkipStatusQueue": k.DisableSkipStatusQueue.Load(), + ret := map[string]any{} + rt := reflect.TypeFor[Knobs]() + rv := reflect.ValueOf(k).Elem() // of *k + for i := 0; i < rt.NumField(); i++ { + name := rt.Field(i).Name + switch v := rv.Field(i).Addr().Interface().(type) { + case *atomic.Bool: + ret[name] = v.Load() + case *syncs.AtomicValue[opt.Bool]: + ret[name] = v.Load() + default: + panic(fmt.Sprintf("unknown field type %T for %v", v, name)) + } } + return ret } |
