ipn/conf: support RemoteConfig in the config file
Add ConfigVAlpha.RemoteConfig so a user-data/cloud-init config can delegate remote control to the tailnet admin (see Prefs.RemoteConfig). Updates #1866 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
committed by
Kristoffer Dalby
parent
f9cd687180
commit
58fcaaf9a5
+3
-1
@@ -92,7 +92,9 @@ single AMI supports two ways of joining a tailnet:
|
|||||||
```
|
```
|
||||||
|
|
||||||
A config present in user-data locks the CLI (`tailscale set`/`up` are
|
A config present in user-data locks the CLI (`tailscale set`/`up` are
|
||||||
rejected) unless it sets `"Locked": false`.
|
rejected) unless it sets `"Locked": false`. Add `"RemoteConfig": true` to
|
||||||
|
hand full remote management of the node to the tailnet admin (see
|
||||||
|
`Prefs.RemoteConfig`) — appropriate for admin-owned fleet devices.
|
||||||
|
|
||||||
- **Interactive (serial console):** launch the AMI with *no* user-data. The
|
- **Interactive (serial console):** launch the AMI with *no* user-data. The
|
||||||
`optional:` prefix means the missing config is not an error, so `tailscaled`
|
`optional:` prefix means the missing config is not an error, so `tailscaled`
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ type ConfigVAlpha struct {
|
|||||||
RunSSHServer opt.Bool `json:",omitempty"` // Tailscale SSH
|
RunSSHServer opt.Bool `json:",omitempty"` // Tailscale SSH
|
||||||
RunWebClient opt.Bool `json:",omitempty"`
|
RunWebClient opt.Bool `json:",omitempty"`
|
||||||
ShieldsUp opt.Bool `json:",omitempty"`
|
ShieldsUp opt.Bool `json:",omitempty"`
|
||||||
|
RemoteConfig opt.Bool `json:",omitzero"` // delegate full remote control to the tailnet admin; see Prefs.RemoteConfig
|
||||||
AutoUpdate *AutoUpdatePrefs `json:",omitempty"`
|
AutoUpdate *AutoUpdatePrefs `json:",omitempty"`
|
||||||
ServeConfigTemp *ServeConfig `json:",omitempty"` // TODO(bradfitz,maisem): make separate stable type for this
|
ServeConfigTemp *ServeConfig `json:",omitempty"` // TODO(bradfitz,maisem): make separate stable type for this
|
||||||
|
|
||||||
@@ -167,6 +168,10 @@ func (c *ConfigVAlpha) ToPrefs() (MaskedPrefs, error) {
|
|||||||
mp.ShieldsUp = c.ShieldsUp.EqualBool(true)
|
mp.ShieldsUp = c.ShieldsUp.EqualBool(true)
|
||||||
mp.ShieldsUpSet = true
|
mp.ShieldsUpSet = true
|
||||||
}
|
}
|
||||||
|
if c.RemoteConfig != "" {
|
||||||
|
mp.RemoteConfig = c.RemoteConfig.EqualBool(true)
|
||||||
|
mp.RemoteConfigSet = true
|
||||||
|
}
|
||||||
if c.AutoUpdate != nil {
|
if c.AutoUpdate != nil {
|
||||||
mp.AutoUpdate = *c.AutoUpdate
|
mp.AutoUpdate = *c.AutoUpdate
|
||||||
mp.AutoUpdateSet = AutoUpdatePrefsMask{ApplySet: true, CheckSet: true}
|
mp.AutoUpdateSet = AutoUpdatePrefsMask{ApplySet: true, CheckSet: true}
|
||||||
|
|||||||
@@ -186,3 +186,28 @@ func TestConfigVAlphaToPrefs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfigVAlphaToPrefsRemoteConfig(t *testing.T) {
|
||||||
|
for name, tt := range map[string]struct {
|
||||||
|
cfg ConfigVAlpha
|
||||||
|
wantSet bool
|
||||||
|
wantVal bool
|
||||||
|
}{
|
||||||
|
"absent": {ConfigVAlpha{Version: "alpha0"}, false, false},
|
||||||
|
"true": {ConfigVAlpha{Version: "alpha0", RemoteConfig: "true"}, true, true},
|
||||||
|
"false": {ConfigVAlpha{Version: "alpha0", RemoteConfig: "false"}, true, false},
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
mp, err := tt.cfg.ToPrefs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if mp.RemoteConfigSet != tt.wantSet {
|
||||||
|
t.Errorf("RemoteConfigSet = %v; want %v", mp.RemoteConfigSet, tt.wantSet)
|
||||||
|
}
|
||||||
|
if mp.RemoteConfig != tt.wantVal {
|
||||||
|
t.Errorf("RemoteConfig = %v; want %v", mp.RemoteConfig, tt.wantVal)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user