mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-11 10:44:41 +00:00
e25f114916
Some fields if `ipn.Prefs` are structs. `ipn.MaskedPrefs` has a single level of boolean `*Set` flags, which doesn't map well to nested structs within `ipn.Prefs`. Change `MaskedPrefs` and `ApplyEdits` to support `FooSet` struct fields that map to a nested struct of `ipn.Prefs` like `AutoUpdates`. Each struct field in `MaskedPrefs` is just a bundle of more `Set` bool fields or other structs. This allows you to have a `Set` flag for any arbitrarily-nested field of `ipn.Prefs`. Also, make `ApplyEdits` match fields between `Prefs` and `MaskedPrefs` by name instead of order, to make it a bit less finicky. It's probably slower but `ipn.ApplyEdits` should not be in any hot path. As a result, `AutoUpdate.Check` and `AutoUpdate.Apply` fields don't clobber each other when set individually. Updates #16247 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
131 lines
4.0 KiB
Go
131 lines
4.0 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package ipn
|
|
|
|
import (
|
|
"net/netip"
|
|
|
|
"tailscale.com/tailcfg"
|
|
"tailscale.com/types/opt"
|
|
"tailscale.com/types/preftype"
|
|
)
|
|
|
|
// ConfigVAlpha is the config file format for the "alpha0" version.
|
|
type ConfigVAlpha struct {
|
|
Version string // "alpha0" for now
|
|
Locked opt.Bool `json:",omitempty"` // whether the config is locked from being changed by 'tailscale set'; it defaults to true
|
|
|
|
ServerURL *string `json:",omitempty"` // defaults to https://controlplane.tailscale.com
|
|
AuthKey *string `json:",omitempty"` // as needed if NeedsLogin. either key or path to a file (if prefixed with "file:")
|
|
Enabled opt.Bool `json:",omitempty"` // wantRunning; empty string defaults to true
|
|
|
|
OperatorUser *string `json:",omitempty"` // local user name who is allowed to operate tailscaled without being root or using sudo
|
|
Hostname *string `json:",omitempty"`
|
|
|
|
AcceptDNS opt.Bool `json:"acceptDNS,omitempty"` // --accept-dns
|
|
AcceptRoutes opt.Bool `json:"acceptRoutes,omitempty"`
|
|
|
|
ExitNode *string `json:"exitNode,omitempty"` // IP, StableID, or MagicDNS base name
|
|
AllowLANWhileUsingExitNode opt.Bool `json:"allowLANWhileUsingExitNode,omitempty"`
|
|
|
|
AdvertiseRoutes []netip.Prefix `json:",omitempty"`
|
|
DisableSNAT opt.Bool `json:",omitempty"`
|
|
|
|
NetfilterMode *string `json:",omitempty"` // "on", "off", "nodivert"
|
|
|
|
PostureChecking opt.Bool `json:",omitempty"`
|
|
RunSSHServer opt.Bool `json:",omitempty"` // Tailscale SSH
|
|
RunWebClient opt.Bool `json:",omitempty"`
|
|
ShieldsUp opt.Bool `json:",omitempty"`
|
|
AutoUpdate *AutoUpdatePrefs `json:",omitempty"`
|
|
ServeConfigTemp *ServeConfig `json:",omitempty"` // TODO(bradfitz,maisem): make separate stable type for this
|
|
|
|
// TODO(bradfitz,maisem): future something like:
|
|
// Profile map[string]*Config // keyed by alice@gmail.com, corp.com (TailnetSID)
|
|
}
|
|
|
|
func (c *ConfigVAlpha) ToPrefs() (MaskedPrefs, error) {
|
|
var mp MaskedPrefs
|
|
if c == nil {
|
|
return mp, nil
|
|
}
|
|
mp.WantRunning = !c.Enabled.EqualBool(false)
|
|
mp.WantRunningSet = mp.WantRunning || c.Enabled != ""
|
|
if c.ServerURL != nil {
|
|
mp.ControlURL = *c.ServerURL
|
|
mp.ControlURLSet = true
|
|
}
|
|
if c.AuthKey != nil && *c.AuthKey != "" {
|
|
mp.LoggedOut = false
|
|
mp.LoggedOutSet = true
|
|
}
|
|
if c.OperatorUser != nil {
|
|
mp.OperatorUser = *c.OperatorUser
|
|
mp.OperatorUserSet = true
|
|
}
|
|
if c.Hostname != nil {
|
|
mp.Hostname = *c.Hostname
|
|
mp.HostnameSet = true
|
|
}
|
|
if c.AcceptDNS != "" {
|
|
mp.CorpDNS = c.AcceptDNS.EqualBool(true)
|
|
mp.CorpDNSSet = true
|
|
}
|
|
if c.AcceptRoutes != "" {
|
|
mp.RouteAll = c.AcceptRoutes.EqualBool(true)
|
|
mp.RouteAllSet = true
|
|
}
|
|
if c.ExitNode != nil {
|
|
ip, err := netip.ParseAddr(*c.ExitNode)
|
|
if err == nil {
|
|
mp.ExitNodeIP = ip
|
|
mp.ExitNodeIPSet = true
|
|
} else {
|
|
mp.ExitNodeID = tailcfg.StableNodeID(*c.ExitNode)
|
|
mp.ExitNodeIDSet = true
|
|
}
|
|
}
|
|
if c.AllowLANWhileUsingExitNode != "" {
|
|
mp.ExitNodeAllowLANAccess = c.AllowLANWhileUsingExitNode.EqualBool(true)
|
|
mp.ExitNodeAllowLANAccessSet = true
|
|
}
|
|
if c.AdvertiseRoutes != nil {
|
|
mp.AdvertiseRoutes = c.AdvertiseRoutes
|
|
mp.AdvertiseRoutesSet = true
|
|
}
|
|
if c.DisableSNAT != "" {
|
|
mp.NoSNAT = c.DisableSNAT.EqualBool(true)
|
|
mp.NoSNAT = true
|
|
}
|
|
if c.NetfilterMode != nil {
|
|
m, err := preftype.ParseNetfilterMode(*c.NetfilterMode)
|
|
if err != nil {
|
|
return mp, err
|
|
}
|
|
mp.NetfilterMode = m
|
|
mp.NetfilterModeSet = true
|
|
}
|
|
if c.PostureChecking != "" {
|
|
mp.PostureChecking = c.PostureChecking.EqualBool(true)
|
|
mp.PostureCheckingSet = true
|
|
}
|
|
if c.RunSSHServer != "" {
|
|
mp.RunSSH = c.RunSSHServer.EqualBool(true)
|
|
mp.RunSSHSet = true
|
|
}
|
|
if c.RunWebClient != "" {
|
|
mp.RunWebClient = c.RunWebClient.EqualBool(true)
|
|
mp.RunWebClientSet = true
|
|
}
|
|
if c.ShieldsUp != "" {
|
|
mp.ShieldsUp = c.ShieldsUp.EqualBool(true)
|
|
mp.ShieldsUpSet = true
|
|
}
|
|
if c.AutoUpdate != nil {
|
|
mp.AutoUpdate = *c.AutoUpdate
|
|
mp.AutoUpdateSet = AutoUpdatePrefsMask{ApplySet: true, CheckSet: true}
|
|
}
|
|
return mp, nil
|
|
}
|