ipn/ipnlocal: make applySysPolicy a method on LocalBackend

Now that applySysPolicy is only called by (*LocalBackend).reconcilePrefsLocked,
we can make it a method to avoid passing state via parameters and to support
future extensibility.

Also factor out exit node-specific logic into applyExitNodeSysPolicyLocked.

Updates tailscale/corp#29969

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2025-07-07 19:05:41 -05:00
committed by Nick Khyl
parent 9bf99741dd
commit 2c630e126b
2 changed files with 37 additions and 21 deletions

View File

@@ -1800,9 +1800,11 @@ var preferencePolicies = []preferencePolicyInfo{
},
}
// applySysPolicy overwrites configured preferences with policies that may be
// applySysPolicyLocked overwrites configured preferences with policies that may be
// configured by the system administrator in an OS-specific way.
func applySysPolicy(prefs *ipn.Prefs, overrideAlwaysOn bool) (anyChange bool) {
//
// b.mu must be held.
func (b *LocalBackend) applySysPolicyLocked(prefs *ipn.Prefs) (anyChange bool) {
if controlURL, err := syspolicy.GetString(syspolicy.ControlURL, prefs.ControlURL); err == nil && prefs.ControlURL != controlURL {
prefs.ControlURL = controlURL
anyChange = true
@@ -1839,6 +1841,34 @@ func applySysPolicy(prefs *ipn.Prefs, overrideAlwaysOn bool) (anyChange bool) {
}
}
if b.applyExitNodeSysPolicyLocked(prefs) {
anyChange = true
}
if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); alwaysOn && !b.overrideAlwaysOn && !prefs.WantRunning {
prefs.WantRunning = true
anyChange = true
}
for _, opt := range preferencePolicies {
if po, err := syspolicy.GetPreferenceOption(opt.key); err == nil {
curVal := opt.get(prefs.View())
newVal := po.ShouldEnable(curVal)
if curVal != newVal {
opt.set(prefs, newVal)
anyChange = true
}
}
}
return anyChange
}
// applyExitNodeSysPolicyLocked applies the exit node policy settings to prefs
// and reports whether any change was made.
//
// b.mu must be held.
func (b *LocalBackend) applyExitNodeSysPolicyLocked(prefs *ipn.Prefs) (anyChange bool) {
if exitNodeIDStr, _ := syspolicy.GetString(syspolicy.ExitNodeID, ""); exitNodeIDStr != "" {
exitNodeID := tailcfg.StableNodeID(exitNodeIDStr)
@@ -1894,22 +1924,6 @@ func applySysPolicy(prefs *ipn.Prefs, overrideAlwaysOn bool) (anyChange bool) {
}
}
if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); alwaysOn && !overrideAlwaysOn && !prefs.WantRunning {
prefs.WantRunning = true
anyChange = true
}
for _, opt := range preferencePolicies {
if po, err := syspolicy.GetPreferenceOption(opt.key); err == nil {
curVal := opt.get(prefs.View())
newVal := po.ShouldEnable(curVal)
if curVal != newVal {
opt.set(prefs, newVal)
anyChange = true
}
}
}
return anyChange
}
@@ -6024,7 +6038,7 @@ func (b *LocalBackend) resolveExitNode() (changed bool) {
//
// b.mu must be held.
func (b *LocalBackend) reconcilePrefsLocked(prefs *ipn.Prefs) (changed bool) {
if applySysPolicy(prefs, b.overrideAlwaysOn) {
if b.applySysPolicyLocked(prefs) {
changed = true
}
if b.resolveExitNodeInPrefsLocked(prefs) {

View File

@@ -2968,7 +2968,8 @@ func TestApplySysPolicy(t *testing.T) {
t.Run("unit", func(t *testing.T) {
prefs := tt.prefs.Clone()
gotAnyChange := applySysPolicy(prefs, false)
lb := newTestLocalBackend(t)
gotAnyChange := lb.applySysPolicyLocked(prefs)
if gotAnyChange && prefs.Equals(&tt.prefs) {
t.Errorf("anyChange but prefs is unchanged: %v", prefs.Pretty())
@@ -3116,7 +3117,8 @@ func TestPreferencePolicyInfo(t *testing.T) {
prefs := defaultPrefs.AsStruct()
pp.set(prefs, tt.initialValue)
gotAnyChange := applySysPolicy(prefs, false)
lb := newTestLocalBackend(t)
gotAnyChange := lb.applySysPolicyLocked(prefs)
if gotAnyChange != tt.wantChange {
t.Errorf("anyChange=%v, want %v", gotAnyChange, tt.wantChange)