mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-16 18:08:40 +00:00
ipn: add user pref for running web client
This is not currently exposed as a user-settable preference through `tailscale up` or `tailscale set`. Instead, the preference is set when turning the web client on and off via localapi. In a subsequent commit, the pref will be used to automatically start the web client on startup when appropriate. Updates tailscale/corp#14335 Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
parent
dd842d4d37
commit
28ad910840
@ -810,6 +810,9 @@ func TestPrefFlagMapping(t *testing.T) {
|
||||
case "Egg":
|
||||
// Not applicable.
|
||||
continue
|
||||
case "RunWebClient":
|
||||
// TODO(tailscale/corp#14335): Currently behind a feature flag.
|
||||
continue
|
||||
}
|
||||
t.Errorf("unexpected new ipn.Pref field %q is not handled by up.go (see addPrefFlagMapping and checkForAccidentalSettingReverts)", prefName)
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ type ConfigVAlpha struct {
|
||||
|
||||
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
|
||||
@ -113,6 +114,10 @@ func (c *ConfigVAlpha) ToPrefs() (MaskedPrefs, error) {
|
||||
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
|
||||
|
@ -38,6 +38,7 @@ var _PrefsCloneNeedsRegeneration = Prefs(struct {
|
||||
ExitNodeAllowLANAccess bool
|
||||
CorpDNS bool
|
||||
RunSSH bool
|
||||
RunWebClient bool
|
||||
WantRunning bool
|
||||
LoggedOut bool
|
||||
ShieldsUp bool
|
||||
|
@ -71,6 +71,7 @@ func (v PrefsView) ExitNodeIP() netip.Addr { return v.ж.ExitNodeIP
|
||||
func (v PrefsView) ExitNodeAllowLANAccess() bool { return v.ж.ExitNodeAllowLANAccess }
|
||||
func (v PrefsView) CorpDNS() bool { return v.ж.CorpDNS }
|
||||
func (v PrefsView) RunSSH() bool { return v.ж.RunSSH }
|
||||
func (v PrefsView) RunWebClient() bool { return v.ж.RunWebClient }
|
||||
func (v PrefsView) WantRunning() bool { return v.ж.WantRunning }
|
||||
func (v PrefsView) LoggedOut() bool { return v.ж.LoggedOut }
|
||||
func (v PrefsView) ShieldsUp() bool { return v.ж.ShieldsUp }
|
||||
@ -100,6 +101,7 @@ var _PrefsViewNeedsRegeneration = Prefs(struct {
|
||||
ExitNodeAllowLANAccess bool
|
||||
CorpDNS bool
|
||||
RunSSH bool
|
||||
RunWebClient bool
|
||||
WantRunning bool
|
||||
LoggedOut bool
|
||||
ShieldsUp bool
|
||||
|
@ -168,6 +168,7 @@ type LocalBackend struct {
|
||||
logFlushFunc func() // or nil if SetLogFlusher wasn't called
|
||||
em *expiryManager // non-nil
|
||||
sshAtomicBool atomic.Bool
|
||||
webclientAtomicBool atomic.Bool
|
||||
shutdownCalled bool // if Shutdown has been called
|
||||
debugSink *capture.Sink
|
||||
sockstatLogger *sockstatlog.Logger
|
||||
@ -2500,6 +2501,7 @@ func (b *LocalBackend) setTCPPortsIntercepted(ports []uint16) {
|
||||
// and shouldInterceptTCPPortAtomic from the prefs p, which may be !Valid().
|
||||
func (b *LocalBackend) setAtomicValuesFromPrefsLocked(p ipn.PrefsView) {
|
||||
b.sshAtomicBool.Store(p.Valid() && p.RunSSH() && envknob.CanSSHD())
|
||||
b.webclientAtomicBool.Store(p.Valid() && p.RunWebClient())
|
||||
|
||||
if !p.Valid() {
|
||||
b.containsViaIPFuncAtomic.Store(tsaddr.FalseContainsIPFunc())
|
||||
@ -2918,6 +2920,11 @@ func (b *LocalBackend) EditPrefs(mp *ipn.MaskedPrefs) (ipn.PrefsView, error) {
|
||||
b.logf("EditPrefs requests SSH, but disabled by envknob; returning error")
|
||||
return ipn.PrefsView{}, errors.New("Tailscale SSH server administratively disabled.")
|
||||
}
|
||||
if p1.RunWebClient && !envknob.Bool("TS_DEBUG_WEB_UI") {
|
||||
b.mu.Unlock()
|
||||
b.logf("EditPrefs requests web client, but disabled by envknob; returning error")
|
||||
return ipn.PrefsView{}, errors.New("web ui flag not set")
|
||||
}
|
||||
if p1.View().Equals(p0) {
|
||||
b.mu.Unlock()
|
||||
return stripKeysFromPrefs(p0), nil
|
||||
@ -3010,6 +3017,9 @@ func (b *LocalBackend) setPrefsLockedOnEntry(caller string, newp *ipn.Prefs) ipn
|
||||
b.sshServer = nil
|
||||
}
|
||||
}
|
||||
if oldp.ShouldWebClientBeRunning() && !newp.ShouldWebClientBeRunning() {
|
||||
b.WebShutdown()
|
||||
}
|
||||
if netMap != nil {
|
||||
newProfile := netMap.UserProfiles[netMap.User()]
|
||||
if newLoginName := newProfile.LoginName; newLoginName != "" {
|
||||
@ -4146,6 +4156,10 @@ func (b *LocalBackend) ResetForClientDisconnect() {
|
||||
|
||||
func (b *LocalBackend) ShouldRunSSH() bool { return b.sshAtomicBool.Load() && envknob.CanSSHD() }
|
||||
|
||||
func (b *LocalBackend) ShouldRunWebClient() bool {
|
||||
return b.webclientAtomicBool.Load() && envknob.Bool("TS_DEBUG_WEB_UI")
|
||||
}
|
||||
|
||||
// ShouldHandleViaIP reports whether ip is an IPv6 address in the
|
||||
// Tailscale ULA's v6 "via" range embedding an IPv4 address to be forwarded to
|
||||
// by Tailscale.
|
||||
|
@ -2249,10 +2249,20 @@ func (h *Handler) serveWeb(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// try to set pref, but ignore errors
|
||||
_, _ = h.b.EditPrefs(&ipn.MaskedPrefs{
|
||||
Prefs: ipn.Prefs{RunWebClient: true},
|
||||
RunWebClientSet: true,
|
||||
})
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
case "/localapi/v0/web/stop":
|
||||
h.b.WebShutdown()
|
||||
// try to set pref, but ignore errors
|
||||
_, _ = h.b.EditPrefs(&ipn.MaskedPrefs{
|
||||
Prefs: ipn.Prefs{RunWebClient: false},
|
||||
RunWebClientSet: true,
|
||||
})
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
default:
|
||||
|
22
ipn/prefs.go
22
ipn/prefs.go
@ -112,6 +112,11 @@ type Prefs struct {
|
||||
// policies as configured by the Tailnet's admin(s).
|
||||
RunSSH bool
|
||||
|
||||
// RunWebClient bool is whether this node should run a web client,
|
||||
// permitting access to peers according to the
|
||||
// policies as configured by the Tailnet's admin(s).
|
||||
RunWebClient bool
|
||||
|
||||
// WantRunning indicates whether networking should be active on
|
||||
// this node.
|
||||
WantRunning bool
|
||||
@ -236,6 +241,7 @@ type MaskedPrefs struct {
|
||||
ExitNodeAllowLANAccessSet bool `json:",omitempty"`
|
||||
CorpDNSSet bool `json:",omitempty"`
|
||||
RunSSHSet bool `json:",omitempty"`
|
||||
RunWebClientSet bool `json:",omitempty"`
|
||||
WantRunningSet bool `json:",omitempty"`
|
||||
LoggedOutSet bool `json:",omitempty"`
|
||||
ShieldsUpSet bool `json:",omitempty"`
|
||||
@ -350,6 +356,9 @@ func (p *Prefs) pretty(goos string) string {
|
||||
if p.RunSSH {
|
||||
sb.WriteString("ssh=true ")
|
||||
}
|
||||
if p.RunWebClient {
|
||||
sb.WriteString("webclient=true ")
|
||||
}
|
||||
if p.LoggedOut {
|
||||
sb.WriteString("loggedout=true ")
|
||||
}
|
||||
@ -431,6 +440,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
|
||||
p.ExitNodeAllowLANAccess == p2.ExitNodeAllowLANAccess &&
|
||||
p.CorpDNS == p2.CorpDNS &&
|
||||
p.RunSSH == p2.RunSSH &&
|
||||
p.RunWebClient == p2.RunWebClient &&
|
||||
p.WantRunning == p2.WantRunning &&
|
||||
p.LoggedOut == p2.LoggedOut &&
|
||||
p.NotepadURLs == p2.NotepadURLs &&
|
||||
@ -691,6 +701,18 @@ func (p *Prefs) ShouldSSHBeRunning() bool {
|
||||
return p.WantRunning && p.RunSSH
|
||||
}
|
||||
|
||||
// ShouldWebClientBeRunning reports whether the web client server should be running based on
|
||||
// the prefs.
|
||||
func (p PrefsView) ShouldWebClientBeRunning() bool {
|
||||
return p.Valid() && p.ж.ShouldWebClientBeRunning()
|
||||
}
|
||||
|
||||
// ShouldWebClientBeRunning reports whether the web client server should be running based on
|
||||
// the prefs.
|
||||
func (p *Prefs) ShouldWebClientBeRunning() bool {
|
||||
return p.WantRunning && p.RunWebClient
|
||||
}
|
||||
|
||||
// PrefsFromBytes deserializes Prefs from a JSON blob.
|
||||
func PrefsFromBytes(b []byte) (*Prefs, error) {
|
||||
p := NewPrefs()
|
||||
|
@ -43,6 +43,7 @@ func TestPrefsEqual(t *testing.T) {
|
||||
"ExitNodeAllowLANAccess",
|
||||
"CorpDNS",
|
||||
"RunSSH",
|
||||
"RunWebClient",
|
||||
"WantRunning",
|
||||
"LoggedOut",
|
||||
"ShieldsUp",
|
||||
|
Loading…
x
Reference in New Issue
Block a user