mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
ipn: introduce app connector advertisement preference and flags
Introduce a preference structure to store the setting for app connector advertisement. Introduce the associated flags: tailscale up --advertise-connector{=true,=false} tailscale set --advertise-connector{=true,=false} ``` % tailscale set --advertise-connector=false % tailscale debug prefs | jq .AppConnector.Advertise false % tailscale set --advertise-connector=true % tailscale debug prefs | jq .AppConnector.Advertise true % tailscale up --advertise-connector=false % tailscale debug prefs | jq .AppConnector.Advertise false % tailscale up --advertise-connector=true % tailscale debug prefs | jq .AppConnector.Advertise true ``` Updates tailscale/corp#15437 Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
parent
09fcbae900
commit
ca4c940a4d
@ -893,6 +893,7 @@ func TestUpdatePrefs(t *testing.T) {
|
|||||||
AdvertiseRoutesSet: true,
|
AdvertiseRoutesSet: true,
|
||||||
AdvertiseTagsSet: true,
|
AdvertiseTagsSet: true,
|
||||||
AllowSingleHostsSet: true,
|
AllowSingleHostsSet: true,
|
||||||
|
AppConnectorSet: true,
|
||||||
ControlURLSet: true,
|
ControlURLSet: true,
|
||||||
CorpDNSSet: true,
|
CorpDNSSet: true,
|
||||||
ExitNodeAllowLANAccessSet: true,
|
ExitNodeAllowLANAccessSet: true,
|
||||||
@ -1131,6 +1132,49 @@ func TestUpdatePrefs(t *testing.T) {
|
|||||||
wantJustEditMP: nil,
|
wantJustEditMP: nil,
|
||||||
env: upCheckEnv{backendState: "Running"},
|
env: upCheckEnv{backendState: "Running"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "advertise_connector",
|
||||||
|
flags: []string{"--advertise-connector"},
|
||||||
|
curPrefs: &ipn.Prefs{
|
||||||
|
ControlURL: ipn.DefaultControlURL,
|
||||||
|
AllowSingleHosts: true,
|
||||||
|
CorpDNS: true,
|
||||||
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
|
},
|
||||||
|
wantJustEditMP: &ipn.MaskedPrefs{
|
||||||
|
AppConnectorSet: true,
|
||||||
|
WantRunningSet: true,
|
||||||
|
},
|
||||||
|
env: upCheckEnv{backendState: "Running"},
|
||||||
|
checkUpdatePrefsMutations: func(t *testing.T, newPrefs *ipn.Prefs) {
|
||||||
|
if !newPrefs.AppConnector.Advertise {
|
||||||
|
t.Errorf("prefs.AppConnector.Advertise not set")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no_advertise_connector",
|
||||||
|
flags: []string{"--advertise-connector=false"},
|
||||||
|
curPrefs: &ipn.Prefs{
|
||||||
|
ControlURL: ipn.DefaultControlURL,
|
||||||
|
AllowSingleHosts: true,
|
||||||
|
CorpDNS: true,
|
||||||
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
|
AppConnector: ipn.AppConnectorPrefs{
|
||||||
|
Advertise: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantJustEditMP: &ipn.MaskedPrefs{
|
||||||
|
AppConnectorSet: true,
|
||||||
|
WantRunningSet: true,
|
||||||
|
},
|
||||||
|
env: upCheckEnv{backendState: "Running"},
|
||||||
|
checkUpdatePrefsMutations: func(t *testing.T, newPrefs *ipn.Prefs) {
|
||||||
|
if newPrefs.AppConnector.Advertise {
|
||||||
|
t.Errorf("prefs.AppConnector.Advertise not unset")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@ -45,6 +45,7 @@ type setArgsT struct {
|
|||||||
hostname string
|
hostname string
|
||||||
advertiseRoutes string
|
advertiseRoutes string
|
||||||
advertiseDefaultRoute bool
|
advertiseDefaultRoute bool
|
||||||
|
advertiseConnector bool
|
||||||
opUser string
|
opUser string
|
||||||
acceptedRisks string
|
acceptedRisks string
|
||||||
profileName string
|
profileName string
|
||||||
@ -67,6 +68,7 @@ func newSetFlagSet(goos string, setArgs *setArgsT) *flag.FlagSet {
|
|||||||
setf.StringVar(&setArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
|
setf.StringVar(&setArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
|
||||||
setf.StringVar(&setArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. \"10.0.0.0/8,192.168.0.0/24\") or empty string to not advertise routes")
|
setf.StringVar(&setArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. \"10.0.0.0/8,192.168.0.0/24\") or empty string to not advertise routes")
|
||||||
setf.BoolVar(&setArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet")
|
setf.BoolVar(&setArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet")
|
||||||
|
setf.BoolVar(&setArgs.advertiseConnector, "advertise-connector", false, "offer to be an exit node for internet traffic for the tailnet")
|
||||||
setf.BoolVar(&setArgs.updateCheck, "update-check", true, "notify about available Tailscale updates")
|
setf.BoolVar(&setArgs.updateCheck, "update-check", true, "notify about available Tailscale updates")
|
||||||
setf.BoolVar(&setArgs.updateApply, "auto-update", false, "automatically update to the latest available version")
|
setf.BoolVar(&setArgs.updateApply, "auto-update", false, "automatically update to the latest available version")
|
||||||
setf.BoolVar(&setArgs.postureChecking, "posture-checking", false, "HIDDEN: allow management plane to gather device posture information")
|
setf.BoolVar(&setArgs.postureChecking, "posture-checking", false, "HIDDEN: allow management plane to gather device posture information")
|
||||||
@ -113,6 +115,9 @@ func runSet(ctx context.Context, args []string) (retErr error) {
|
|||||||
Check: setArgs.updateCheck,
|
Check: setArgs.updateCheck,
|
||||||
Apply: setArgs.updateApply,
|
Apply: setArgs.updateApply,
|
||||||
},
|
},
|
||||||
|
AppConnector: ipn.AppConnectorPrefs{
|
||||||
|
Advertise: setArgs.advertiseConnector,
|
||||||
|
},
|
||||||
PostureChecking: setArgs.postureChecking,
|
PostureChecking: setArgs.postureChecking,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,7 @@ func newUpFlagSet(goos string, upArgs *upArgsT, cmd string) *flag.FlagSet {
|
|||||||
upf.StringVar(&upArgs.advertiseTags, "advertise-tags", "", "comma-separated ACL tags to request; each must start with \"tag:\" (e.g. \"tag:eng,tag:montreal,tag:ssh\")")
|
upf.StringVar(&upArgs.advertiseTags, "advertise-tags", "", "comma-separated ACL tags to request; each must start with \"tag:\" (e.g. \"tag:eng,tag:montreal,tag:ssh\")")
|
||||||
upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
|
upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS")
|
||||||
upf.StringVar(&upArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. \"10.0.0.0/8,192.168.0.0/24\") or empty string to not advertise routes")
|
upf.StringVar(&upArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. \"10.0.0.0/8,192.168.0.0/24\") or empty string to not advertise routes")
|
||||||
|
upf.BoolVar(&upArgs.advertiseConnector, "advertise-connector", false, "advertise this node as an app connector")
|
||||||
upf.BoolVar(&upArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet")
|
upf.BoolVar(&upArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet")
|
||||||
|
|
||||||
if safesocket.GOOSUsesPeerCreds(goos) {
|
if safesocket.GOOSUsesPeerCreds(goos) {
|
||||||
@ -165,6 +166,7 @@ type upArgsT struct {
|
|||||||
advertiseRoutes string
|
advertiseRoutes string
|
||||||
advertiseDefaultRoute bool
|
advertiseDefaultRoute bool
|
||||||
advertiseTags string
|
advertiseTags string
|
||||||
|
advertiseConnector bool
|
||||||
snat bool
|
snat bool
|
||||||
netfilterMode string
|
netfilterMode string
|
||||||
authKeyOrFile string // "secret" or "file:/path/to/secret"
|
authKeyOrFile string // "secret" or "file:/path/to/secret"
|
||||||
@ -283,6 +285,7 @@ func prefsFromUpArgs(upArgs upArgsT, warnf logger.Logf, st *ipnstate.Status, goo
|
|||||||
prefs.ForceDaemon = upArgs.forceDaemon
|
prefs.ForceDaemon = upArgs.forceDaemon
|
||||||
prefs.OperatorUser = upArgs.opUser
|
prefs.OperatorUser = upArgs.opUser
|
||||||
prefs.ProfileName = upArgs.profileName
|
prefs.ProfileName = upArgs.profileName
|
||||||
|
prefs.AppConnector.Advertise = upArgs.advertiseConnector
|
||||||
|
|
||||||
if goos == "linux" {
|
if goos == "linux" {
|
||||||
prefs.NoSNAT = !upArgs.snat
|
prefs.NoSNAT = !upArgs.snat
|
||||||
@ -730,6 +733,7 @@ func init() {
|
|||||||
addPrefFlagMapping("nickname", "ProfileName")
|
addPrefFlagMapping("nickname", "ProfileName")
|
||||||
addPrefFlagMapping("update-check", "AutoUpdate")
|
addPrefFlagMapping("update-check", "AutoUpdate")
|
||||||
addPrefFlagMapping("auto-update", "AutoUpdate")
|
addPrefFlagMapping("auto-update", "AutoUpdate")
|
||||||
|
addPrefFlagMapping("advertise-connector", "AppConnector")
|
||||||
addPrefFlagMapping("posture-checking", "PostureChecking")
|
addPrefFlagMapping("posture-checking", "PostureChecking")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,6 +969,8 @@ func prefsToFlags(env upCheckEnv, prefs *ipn.Prefs) (flagVal map[string]any) {
|
|||||||
set(sb.String())
|
set(sb.String())
|
||||||
case "advertise-exit-node":
|
case "advertise-exit-node":
|
||||||
set(hasExitNodeRoutes(prefs.AdvertiseRoutes))
|
set(hasExitNodeRoutes(prefs.AdvertiseRoutes))
|
||||||
|
case "advertise-connector":
|
||||||
|
set(prefs.AppConnector.Advertise)
|
||||||
case "snat-subnet-routes":
|
case "snat-subnet-routes":
|
||||||
set(!prefs.NoSNAT)
|
set(!prefs.NoSNAT)
|
||||||
case "netfilter-mode":
|
case "netfilter-mode":
|
||||||
|
@ -53,6 +53,7 @@ func (src *Prefs) Clone() *Prefs {
|
|||||||
OperatorUser string
|
OperatorUser string
|
||||||
ProfileName string
|
ProfileName string
|
||||||
AutoUpdate AutoUpdatePrefs
|
AutoUpdate AutoUpdatePrefs
|
||||||
|
AppConnector AppConnectorPrefs
|
||||||
PostureChecking bool
|
PostureChecking bool
|
||||||
Persist *persist.Persist
|
Persist *persist.Persist
|
||||||
}{})
|
}{})
|
||||||
|
@ -88,6 +88,7 @@ func (v PrefsView) NetfilterMode() preftype.NetfilterMode { return v.ж.Netfilte
|
|||||||
func (v PrefsView) OperatorUser() string { return v.ж.OperatorUser }
|
func (v PrefsView) OperatorUser() string { return v.ж.OperatorUser }
|
||||||
func (v PrefsView) ProfileName() string { return v.ж.ProfileName }
|
func (v PrefsView) ProfileName() string { return v.ж.ProfileName }
|
||||||
func (v PrefsView) AutoUpdate() AutoUpdatePrefs { return v.ж.AutoUpdate }
|
func (v PrefsView) AutoUpdate() AutoUpdatePrefs { return v.ж.AutoUpdate }
|
||||||
|
func (v PrefsView) AppConnector() AppConnectorPrefs { return v.ж.AppConnector }
|
||||||
func (v PrefsView) PostureChecking() bool { return v.ж.PostureChecking }
|
func (v PrefsView) PostureChecking() bool { return v.ж.PostureChecking }
|
||||||
func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() }
|
func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() }
|
||||||
|
|
||||||
@ -116,6 +117,7 @@ func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.
|
|||||||
OperatorUser string
|
OperatorUser string
|
||||||
ProfileName string
|
ProfileName string
|
||||||
AutoUpdate AutoUpdatePrefs
|
AutoUpdate AutoUpdatePrefs
|
||||||
|
AppConnector AppConnectorPrefs
|
||||||
PostureChecking bool
|
PostureChecking bool
|
||||||
Persist *persist.Persist
|
Persist *persist.Persist
|
||||||
}{})
|
}{})
|
||||||
|
21
ipn/prefs.go
21
ipn/prefs.go
@ -205,6 +205,10 @@ type Prefs struct {
|
|||||||
// AutoUpdatePrefs docs for more details.
|
// AutoUpdatePrefs docs for more details.
|
||||||
AutoUpdate AutoUpdatePrefs
|
AutoUpdate AutoUpdatePrefs
|
||||||
|
|
||||||
|
// AppConnector sets the app connector preferences for the node agent. See
|
||||||
|
// AppConnectorPrefs docs for more details.
|
||||||
|
AppConnector AppConnectorPrefs
|
||||||
|
|
||||||
// PostureChecking enables the collection of information used for device
|
// PostureChecking enables the collection of information used for device
|
||||||
// posture checks.
|
// posture checks.
|
||||||
PostureChecking bool
|
PostureChecking bool
|
||||||
@ -229,6 +233,13 @@ type AutoUpdatePrefs struct {
|
|||||||
Apply bool
|
Apply bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppConnectorPrefs are the app connector settings for the node agent.
|
||||||
|
type AppConnectorPrefs struct {
|
||||||
|
// Advertise specifies whether the app connector subsystem is advertising
|
||||||
|
// this node as a connector.
|
||||||
|
Advertise bool
|
||||||
|
}
|
||||||
|
|
||||||
// MaskedPrefs is a Prefs with an associated bitmask of which fields are set.
|
// MaskedPrefs is a Prefs with an associated bitmask of which fields are set.
|
||||||
type MaskedPrefs struct {
|
type MaskedPrefs struct {
|
||||||
Prefs
|
Prefs
|
||||||
@ -256,6 +267,7 @@ type MaskedPrefs struct {
|
|||||||
OperatorUserSet bool `json:",omitempty"`
|
OperatorUserSet bool `json:",omitempty"`
|
||||||
ProfileNameSet bool `json:",omitempty"`
|
ProfileNameSet bool `json:",omitempty"`
|
||||||
AutoUpdateSet bool `json:",omitempty"`
|
AutoUpdateSet bool `json:",omitempty"`
|
||||||
|
AppConnectorSet bool `json:",omitempty"`
|
||||||
PostureCheckingSet bool `json:",omitempty"`
|
PostureCheckingSet bool `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +410,7 @@ func (p *Prefs) pretty(goos string) string {
|
|||||||
fmt.Fprintf(&sb, "op=%q ", p.OperatorUser)
|
fmt.Fprintf(&sb, "op=%q ", p.OperatorUser)
|
||||||
}
|
}
|
||||||
sb.WriteString(p.AutoUpdate.Pretty())
|
sb.WriteString(p.AutoUpdate.Pretty())
|
||||||
|
sb.WriteString(p.AppConnector.Pretty())
|
||||||
if p.Persist != nil {
|
if p.Persist != nil {
|
||||||
sb.WriteString(p.Persist.Pretty())
|
sb.WriteString(p.Persist.Pretty())
|
||||||
} else {
|
} else {
|
||||||
@ -455,6 +468,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
|
|||||||
p.Persist.Equals(p2.Persist) &&
|
p.Persist.Equals(p2.Persist) &&
|
||||||
p.ProfileName == p2.ProfileName &&
|
p.ProfileName == p2.ProfileName &&
|
||||||
p.AutoUpdate == p2.AutoUpdate &&
|
p.AutoUpdate == p2.AutoUpdate &&
|
||||||
|
p.AppConnector == p2.AppConnector &&
|
||||||
p.PostureChecking == p2.PostureChecking
|
p.PostureChecking == p2.PostureChecking
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +482,13 @@ func (au AutoUpdatePrefs) Pretty() string {
|
|||||||
return "update=off "
|
return "update=off "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ap AppConnectorPrefs) Pretty() string {
|
||||||
|
if ap.Advertise {
|
||||||
|
return "appconnector=advertise "
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func compareIPNets(a, b []netip.Prefix) bool {
|
func compareIPNets(a, b []netip.Prefix) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
|
@ -58,6 +58,7 @@ func TestPrefsEqual(t *testing.T) {
|
|||||||
"OperatorUser",
|
"OperatorUser",
|
||||||
"ProfileName",
|
"ProfileName",
|
||||||
"AutoUpdate",
|
"AutoUpdate",
|
||||||
|
"AppConnector",
|
||||||
"PostureChecking",
|
"PostureChecking",
|
||||||
"Persist",
|
"Persist",
|
||||||
}
|
}
|
||||||
@ -306,6 +307,16 @@ func TestPrefsEqual(t *testing.T) {
|
|||||||
&Prefs{AutoUpdate: AutoUpdatePrefs{Check: true, Apply: false}},
|
&Prefs{AutoUpdate: AutoUpdatePrefs{Check: true, Apply: false}},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&Prefs{AppConnector: AppConnectorPrefs{Advertise: true}},
|
||||||
|
&Prefs{AppConnector: AppConnectorPrefs{Advertise: true}},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&Prefs{AppConnector: AppConnectorPrefs{Advertise: true}},
|
||||||
|
&Prefs{AppConnector: AppConnectorPrefs{Advertise: false}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
&Prefs{PostureChecking: true},
|
&Prefs{PostureChecking: true},
|
||||||
&Prefs{PostureChecking: true},
|
&Prefs{PostureChecking: true},
|
||||||
@ -516,6 +527,24 @@ func TestPrefsPretty(t *testing.T) {
|
|||||||
"linux",
|
"linux",
|
||||||
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off update=on Persist=nil}`,
|
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off update=on Persist=nil}`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Prefs{
|
||||||
|
AppConnector: AppConnectorPrefs{
|
||||||
|
Advertise: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"linux",
|
||||||
|
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off update=off appconnector=advertise Persist=nil}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefs{
|
||||||
|
AppConnector: AppConnectorPrefs{
|
||||||
|
Advertise: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"linux",
|
||||||
|
`Prefs{ra=false mesh=false dns=false want=false routes=[] nf=off update=off Persist=nil}`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
got := tt.p.pretty(tt.os)
|
got := tt.p.pretty(tt.os)
|
||||||
|
Loading…
Reference in New Issue
Block a user