cmd/tailscale/cli: add ability to set short names for profiles
This adds a `--nickname` flag to `tailscale login|set`. Updates #713 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
575fd5f22b
commit
b94b91c168
|
@ -480,6 +480,19 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||
distro: "", // not Synology
|
||||
want: accidentalUpPrefix + " --hostname=foo --accept-routes",
|
||||
},
|
||||
{
|
||||
name: "profile_name_ignored_in_up",
|
||||
flags: []string{"--hostname=foo"},
|
||||
curPrefs: &ipn.Prefs{
|
||||
ControlURL: "https://login.tailscale.com",
|
||||
CorpDNS: true,
|
||||
AllowSingleHosts: true,
|
||||
NetfilterMode: preftype.NetfilterOn,
|
||||
ProfileName: "foo",
|
||||
},
|
||||
goos: "linux",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -27,6 +27,6 @@ This command is currently in alpha and may change in the future.`,
|
|||
if err := localClient.SwitchToEmptyProfile(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return runUp(ctx, args, loginArgs)
|
||||
return runUp(ctx, "login", args, loginArgs)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -43,11 +43,13 @@ type setArgsT struct {
|
|||
advertiseDefaultRoute bool
|
||||
opUser string
|
||||
acceptedRisks string
|
||||
profileName string
|
||||
}
|
||||
|
||||
func newSetFlagSet(goos string, setArgs *setArgsT) *flag.FlagSet {
|
||||
setf := newFlagSet("set")
|
||||
|
||||
setf.StringVar(&setArgs.profileName, "nickname", "", "nickname for the login profile")
|
||||
setf.BoolVar(&setArgs.acceptRoutes, "accept-routes", false, "accept routes advertised by other Tailscale nodes")
|
||||
setf.BoolVar(&setArgs.acceptDNS, "accept-dns", false, "accept DNS configuration from the admin panel")
|
||||
setf.StringVar(&setArgs.exitNodeIP, "exit-node", "", "Tailscale exit node (IP or base name) for internet traffic, or empty string to not use an exit node")
|
||||
|
@ -81,6 +83,7 @@ func runSet(ctx context.Context, args []string) (retErr error) {
|
|||
|
||||
maskedPrefs := &ipn.MaskedPrefs{
|
||||
Prefs: ipn.Prefs{
|
||||
ProfileName: setArgs.profileName,
|
||||
RouteAll: setArgs.acceptRoutes,
|
||||
CorpDNS: setArgs.acceptDNS,
|
||||
ExitNodeAllowLANAccess: setArgs.exitNodeAllowLANAccess,
|
||||
|
@ -132,6 +135,11 @@ func runSet(ctx context.Context, args []string) (retErr error) {
|
|||
return err
|
||||
}
|
||||
}
|
||||
checkPrefs := curPrefs.Clone()
|
||||
checkPrefs.ApplyEdits(maskedPrefs)
|
||||
if err := localClient.CheckPrefs(ctx, checkPrefs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = localClient.EditPrefs(ctx, maskedPrefs)
|
||||
return err
|
||||
|
|
|
@ -60,7 +60,7 @@ settings.)
|
|||
`),
|
||||
FlagSet: upFlagSet,
|
||||
Exec: func(ctx context.Context, args []string) error {
|
||||
return runUp(ctx, args, upArgsGlobal)
|
||||
return runUp(ctx, "up", args, upArgsGlobal)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,10 @@ func newUpFlagSet(goos string, upArgs *upArgsT, cmd string) *flag.FlagSet {
|
|||
}
|
||||
upf.DurationVar(&upArgs.timeout, "timeout", 0, "maximum amount of time to wait for tailscaled to enter a Running state; default (0s) blocks forever")
|
||||
|
||||
if cmd == "login" {
|
||||
upf.StringVar(&upArgs.profileName, "nickname", "", "short name for the login profile")
|
||||
}
|
||||
|
||||
if cmd == "up" {
|
||||
// Some flags are only for "up", not "login".
|
||||
upf.BoolVar(&upArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
|
||||
|
@ -129,6 +133,7 @@ func newUpFlagSet(goos string, upArgs *upArgsT, cmd string) *flag.FlagSet {
|
|||
upf.BoolVar(&upArgs.forceReauth, "force-reauth", false, "force reauthentication")
|
||||
registerAcceptRiskFlag(upf, &upArgs.acceptedRisks)
|
||||
}
|
||||
|
||||
return upf
|
||||
}
|
||||
|
||||
|
@ -163,6 +168,7 @@ type upArgsT struct {
|
|||
json bool
|
||||
timeout time.Duration
|
||||
acceptedRisks string
|
||||
profileName string
|
||||
}
|
||||
|
||||
func (a upArgsT) getAuthKey() (string, error) {
|
||||
|
@ -343,6 +349,7 @@ func prefsFromUpArgs(upArgs upArgsT, warnf logger.Logf, st *ipnstate.Status, goo
|
|||
prefs.Hostname = upArgs.hostname
|
||||
prefs.ForceDaemon = upArgs.forceDaemon
|
||||
prefs.OperatorUser = upArgs.opUser
|
||||
prefs.ProfileName = upArgs.profileName
|
||||
|
||||
if goos == "linux" {
|
||||
prefs.NoSNAT = !upArgs.snat
|
||||
|
@ -437,7 +444,7 @@ func presentSSHToggleRisk(wantSSH, haveSSH bool, acceptedRisks string) error {
|
|||
return presentRiskToUser(riskLoseSSH, `You are connected using Tailscale SSH; this action will result in your session disconnecting.`, acceptedRisks)
|
||||
}
|
||||
|
||||
func runUp(ctx context.Context, args []string, upArgs upArgsT) (retErr error) {
|
||||
func runUp(ctx context.Context, cmd string, args []string, upArgs upArgsT) (retErr error) {
|
||||
var egg bool
|
||||
if len(args) > 0 {
|
||||
egg = fmt.Sprint(args) == "[up down down left right left right b a]"
|
||||
|
@ -496,6 +503,11 @@ func runUp(ctx context.Context, args []string, upArgs upArgsT) (retErr error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmd == "up" {
|
||||
// "tailscale up" should not be able to change the
|
||||
// profile name.
|
||||
prefs.ProfileName = curPrefs.ProfileName
|
||||
}
|
||||
|
||||
env := upCheckEnv{
|
||||
goos: effectiveGOOS(),
|
||||
|
@ -764,6 +776,7 @@ func init() {
|
|||
addPrefFlagMapping("unattended", "ForceDaemon")
|
||||
addPrefFlagMapping("operator", "OperatorUser")
|
||||
addPrefFlagMapping("ssh", "RunSSH")
|
||||
addPrefFlagMapping("nickname", "ProfileName")
|
||||
}
|
||||
|
||||
func addPrefFlagMapping(flagName string, prefNames ...string) {
|
||||
|
|
|
@ -2109,6 +2109,9 @@ func (b *LocalBackend) checkPrefsLocked(p *ipn.Prefs) error {
|
|||
// Keep this one just for testing.
|
||||
errs = append(errs, errors.New("bad hostname [test]"))
|
||||
}
|
||||
if err := b.checkProfileNameLocked(p); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if err := b.checkSSHPrefsLocked(p); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
@ -2226,6 +2229,23 @@ func (b *LocalBackend) EditPrefs(mp *ipn.MaskedPrefs) (ipn.PrefsView, error) {
|
|||
return stripKeysFromPrefs(newPrefs), nil
|
||||
}
|
||||
|
||||
func (b *LocalBackend) checkProfileNameLocked(p *ipn.Prefs) error {
|
||||
if p.ProfileName == "" {
|
||||
// It is always okay to clear the profile name.
|
||||
return nil
|
||||
}
|
||||
id := b.pm.ProfileIDForName(p.ProfileName)
|
||||
if id == "" {
|
||||
// No profile with that name exists. That's fine.
|
||||
return nil
|
||||
}
|
||||
if id != b.pm.CurrentProfile().ID {
|
||||
// Name is already in use by another profile.
|
||||
return fmt.Errorf("profile name %q already in use", p.ProfileName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPrefs saves new user preferences and propagates them throughout
|
||||
// the system. Implements Backend.
|
||||
func (b *LocalBackend) SetPrefs(newp *ipn.Prefs) {
|
||||
|
|
|
@ -96,6 +96,16 @@ func (pm *profileManager) findProfilesByUserID(userID tailcfg.UserID) []*ipn.Log
|
|||
return out
|
||||
}
|
||||
|
||||
// ProfileIDForName returns the profile ID for the profile with the
|
||||
// given name. It returns "" if no such profile exists.
|
||||
func (pm *profileManager) ProfileIDForName(name string) ipn.ProfileID {
|
||||
p := pm.findProfileByName(name)
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
return p.ID
|
||||
}
|
||||
|
||||
func (pm *profileManager) findProfileByName(name string) *ipn.LoginProfile {
|
||||
for _, p := range pm.knownProfiles {
|
||||
if p.Name == name {
|
||||
|
|
|
@ -190,7 +190,7 @@ type Prefs struct {
|
|||
// operate tailscaled without being root or using sudo.
|
||||
OperatorUser string `json:",omitempty"`
|
||||
|
||||
// ProfileName is the desired name of the profile. If empty, then the users
|
||||
// ProfileName is the desired name of the profile. If empty, then the user's
|
||||
// LoginName is used. It is only used for display purposes in the client UI
|
||||
// and CLI.
|
||||
ProfileName string `json:",omitempty"`
|
||||
|
|
Loading…
Reference in New Issue