types/config, types/node: model default-auto-update from auto_update.enabled
Tailscale stamps tailcfg.NodeAttrDefaultAutoUpdate on every node's CapMap with a JSON bool reflecting the tailnet-wide auto-update default. Headscale grows an auto_update.enabled config option and emits the cap accordingly from TailNode -- the cap leaves the unmodelledTailnetStateCaps strip list and is compared in full by the nodeAttrs compat suite. testNodeAttrsSuccess drives cfg.AutoUpdate.Enabled from tf.Input.Tailnet.Settings.DevicesAutoUpdatesOn so each capture's expected emission matches the SaaS state it was taken under. Two captures cover both branches: - nodeattrs-tailnet-devices-auto-updates-on -> [true] - nodeattrs-tailnet-devices-auto-updates-off -> [false] The Tailscale v2 TailnetSettings API does not expose the Send Files toggle, so the compat suite cannot vary cfg.Taildrop.Enabled per capture. TestTaildropDisabledWithholdsFileSharingCap covers the off path directly in servertest.
This commit is contained in:
parent
408f4022e4
commit
64d13f77e8
10 changed files with 9519 additions and 854 deletions
|
|
@ -130,8 +130,9 @@ type Config struct {
|
|||
|
||||
OIDC OIDCConfig
|
||||
|
||||
LogTail LogTailConfig
|
||||
Taildrop TaildropConfig
|
||||
LogTail LogTailConfig
|
||||
Taildrop TaildropConfig
|
||||
AutoUpdate AutoUpdateConfig
|
||||
|
||||
CLI CLIConfig
|
||||
|
||||
|
|
@ -253,6 +254,15 @@ type TaildropConfig struct {
|
|||
Enabled bool
|
||||
}
|
||||
|
||||
// AutoUpdateConfig controls the tailnet-wide default for client
|
||||
// auto-update. When Enabled is true, headscale emits the
|
||||
// [tailcfg.NodeAttrDefaultAutoUpdate] cap with value [true] on every
|
||||
// node's CapMap; clients fall back to that default unless they have
|
||||
// opted in or out locally.
|
||||
type AutoUpdateConfig struct {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
type CLIConfig struct {
|
||||
Address string
|
||||
APIKey string `json:"-"` // never serialise the headscale admin API key
|
||||
|
|
@ -428,6 +438,7 @@ func LoadConfig(path string, isFile bool) error {
|
|||
|
||||
viper.SetDefault("logtail.enabled", false)
|
||||
viper.SetDefault("taildrop.enabled", true)
|
||||
viper.SetDefault("auto_update.enabled", false)
|
||||
|
||||
viper.SetDefault("node.expiry", "0")
|
||||
viper.SetDefault("node.ephemeral.inactivity_timeout", "120s")
|
||||
|
|
@ -1230,6 +1241,9 @@ func LoadServerConfig() (*Config, error) {
|
|||
Taildrop: TaildropConfig{
|
||||
Enabled: viper.GetBool("taildrop.enabled"),
|
||||
},
|
||||
AutoUpdate: AutoUpdateConfig{
|
||||
Enabled: viper.GetBool("auto_update.enabled"),
|
||||
},
|
||||
|
||||
Policy: policyConfig(),
|
||||
|
||||
|
|
|
|||
|
|
@ -1203,6 +1203,18 @@ func (nv NodeView) TailNode(
|
|||
capMap[tailcfg.CapabilityFileSharing] = []tailcfg.RawMessage{}
|
||||
}
|
||||
|
||||
// default-auto-update is always emitted; the value is a JSON bool
|
||||
// reflecting cfg.AutoUpdate.Enabled. Clients read this on first
|
||||
// netmap and store the default locally; subsequent control-plane
|
||||
// changes are ignored unless the client has not yet opted in or
|
||||
// out.
|
||||
autoUpdateVal := tailcfg.RawMessage("false")
|
||||
if cfg.AutoUpdate.Enabled {
|
||||
autoUpdateVal = tailcfg.RawMessage("true")
|
||||
}
|
||||
|
||||
capMap[tailcfg.NodeAttrDefaultAutoUpdate] = []tailcfg.RawMessage{autoUpdateVal}
|
||||
|
||||
// Policy nodeAttrs overlay the baseline on the self view. Peers
|
||||
// pass nil; their CapMap is replaced downstream by [policyv2.PeerCapMap].
|
||||
maps.Copy(capMap, selfPolicyCaps)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue