cmd/tailscale/cli: don't require explicit --operator if it matches $USER

This doesn't make --operator implicit (which we might do in the
future), but it at least doesn't require repeating it in the future
when it already matches $USER.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2021-04-21 15:47:59 -07:00
parent 2f17a34242
commit dedbd483ea
2 changed files with 41 additions and 3 deletions

View File

@ -40,6 +40,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
name string name string
flagSet map[string]bool flagSet map[string]bool
curPrefs *ipn.Prefs curPrefs *ipn.Prefs
curUser string // os.Getenv("USER") on the client side
mp *ipn.MaskedPrefs mp *ipn.MaskedPrefs
want string want string
}{ }{
@ -148,11 +149,43 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
}, },
want: "", want: "",
}, },
{
name: "implicit_operator_change",
flagSet: f("hostname"),
curPrefs: &ipn.Prefs{
ControlURL: ipn.DefaultControlURL,
OperatorUser: "alice",
},
curUser: "eve",
mp: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
ControlURL: ipn.DefaultControlURL,
},
ControlURLSet: true,
},
want: `'tailscale up' without --reset requires all preferences with changing values to be explicitly mentioned; --operator is not specified but its default value of "" differs from current value "alice"`,
},
{
name: "implicit_operator_matches_shell_user",
flagSet: f("hostname"),
curPrefs: &ipn.Prefs{
ControlURL: ipn.DefaultControlURL,
OperatorUser: "alice",
},
curUser: "alice",
mp: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
ControlURL: ipn.DefaultControlURL,
},
ControlURLSet: true,
},
want: "",
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
var got string var got string
if err := checkForAccidentalSettingReverts(tt.flagSet, tt.curPrefs, tt.mp); err != nil { if err := checkForAccidentalSettingReverts(tt.flagSet, tt.curPrefs, tt.mp, tt.curUser); err != nil {
got = err.Error() got = err.Error()
} }
if got != tt.want { if got != tt.want {

View File

@ -285,7 +285,7 @@ func runUp(ctx context.Context, args []string) error {
}) })
if !upArgs.reset { if !upArgs.reset {
if err := checkForAccidentalSettingReverts(flagSet, curPrefs, mp); err != nil { if err := checkForAccidentalSettingReverts(flagSet, curPrefs, mp, os.Getenv("USER")); err != nil {
fatalf("%s", err) fatalf("%s", err)
} }
} }
@ -500,7 +500,7 @@ func updateMaskedPrefsFromUpFlag(mp *ipn.MaskedPrefs, flagName string) {
// //
// mp is the mask of settings actually set, where mp.Prefs is the new // mp is the mask of settings actually set, where mp.Prefs is the new
// preferences to set, including any values set from implicit flags. // preferences to set, including any values set from implicit flags.
func checkForAccidentalSettingReverts(flagSet map[string]bool, curPrefs *ipn.Prefs, mp *ipn.MaskedPrefs) error { func checkForAccidentalSettingReverts(flagSet map[string]bool, curPrefs *ipn.Prefs, mp *ipn.MaskedPrefs, curUser string) error {
if len(flagSet) == 0 { if len(flagSet) == 0 {
// A bare "tailscale up" is a special case to just // A bare "tailscale up" is a special case to just
// mean bringing the network up without any changes. // mean bringing the network up without any changes.
@ -543,6 +543,11 @@ func checkForAccidentalSettingReverts(flagSet map[string]bool, curPrefs *ipn.Pre
if reflect.DeepEqual(exi, imi) { if reflect.DeepEqual(exi, imi) {
continue continue
} }
if flagName == "operator" && imi == "" && exi == curUser {
// Don't require setting operator if the current user matches
// the configured operator.
continue
}
switch flagName { switch flagName {
case "": case "":
errs = append(errs, fmt.Errorf("'tailscale up' without --reset requires all preferences with changing values to be explicitly mentioned; this command would change the value of flagless pref %q", prefName)) errs = append(errs, fmt.Errorf("'tailscale up' without --reset requires all preferences with changing values to be explicitly mentioned; this command would change the value of flagless pref %q", prefName))