tailcfg, controlclient: add DisplayName field to tailcfg.Node and populate it from controlclient (#1191)

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
pull/1199/head
Sonia Appasamy 4 years ago committed by GitHub
parent 4fea604979
commit 567c5a6d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -113,7 +113,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/types/strbuilder from tailscale.com/net/packet tailscale.com/types/strbuilder from tailscale.com/net/packet
tailscale.com/types/structs from tailscale.com/control/controlclient+ tailscale.com/types/structs from tailscale.com/control/controlclient+
tailscale.com/types/wgkey from tailscale.com/control/controlclient+ tailscale.com/types/wgkey from tailscale.com/control/controlclient+
tailscale.com/util/dnsname from tailscale.com/wgengine/tsdns tailscale.com/util/dnsname from tailscale.com/wgengine/tsdns+
LW tailscale.com/util/endian from tailscale.com/net/netns+ LW tailscale.com/util/endian from tailscale.com/net/netns+
tailscale.com/util/lineread from tailscale.com/control/controlclient+ tailscale.com/util/lineread from tailscale.com/control/controlclient+
tailscale.com/util/pidowner from tailscale.com/ipn/ipnserver tailscale.com/util/pidowner from tailscale.com/ipn/ipnserver

@ -775,6 +775,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, maxPolls int, cb func(*Netw
MachineKey: machinePubKey, MachineKey: machinePubKey,
Expiry: resp.Node.KeyExpiry, Expiry: resp.Node.KeyExpiry,
Name: resp.Node.Name, Name: resp.Node.Name,
DisplayName: resp.Node.DisplayName,
Addresses: resp.Node.Addresses, Addresses: resp.Node.Addresses,
Peers: resp.Peers, Peers: resp.Peers,
LocalPort: localPort, LocalPort: localPort,
@ -799,6 +800,9 @@ func (c *Direct) sendMapRequest(ctx context.Context, maxPolls int, cb func(*Netw
} }
addUserProfile(nm.User) addUserProfile(nm.User)
for _, peer := range resp.Peers { for _, peer := range resp.Peers {
if peer.DisplayName == "" {
peer.DisplayName = peer.DefaultDisplayName()
}
if !peer.Sharer.IsZero() { if !peer.Sharer.IsZero() {
if c.keepSharerAndUserSplit { if c.keepSharerAndUserSplit {
addUserProfile(peer.Sharer) addUserProfile(peer.Sharer)
@ -808,6 +812,9 @@ func (c *Direct) sendMapRequest(ctx context.Context, maxPolls int, cb func(*Netw
} }
addUserProfile(peer.User) addUserProfile(peer.User)
} }
if resp.Node.DisplayName == "" {
nm.DisplayName = resp.Node.DefaultDisplayName()
}
if resp.Node.MachineAuthorized { if resp.Node.MachineAuthorized {
nm.MachineStatus = tailcfg.MachineAuthorized nm.MachineStatus = tailcfg.MachineAuthorized
} else { } else {

@ -28,7 +28,9 @@ type NetworkMap struct {
PrivateKey wgkey.Private PrivateKey wgkey.Private
Expiry time.Time Expiry time.Time
// Name is the DNS name assigned to this node. // Name is the DNS name assigned to this node.
Name string Name string
// DisplayName is the title to show for the node in client UIs.
DisplayName string
Addresses []netaddr.IPPrefix Addresses []netaddr.IPPrefix
LocalPort uint16 // used for debugging LocalPort uint16 // used for debugging
MachineStatus tailcfg.MachineStatus MachineStatus tailcfg.MachineStatus

@ -20,6 +20,7 @@ import (
"tailscale.com/types/key" "tailscale.com/types/key"
"tailscale.com/types/opt" "tailscale.com/types/opt"
"tailscale.com/types/structs" "tailscale.com/types/structs"
"tailscale.com/util/dnsname"
) )
// CurrentMapRequestVersion is the current MapRequest.Version value. // CurrentMapRequestVersion is the current MapRequest.Version value.
@ -160,6 +161,12 @@ type Node struct {
StableID StableNodeID StableID StableNodeID
Name string // DNS Name string // DNS
// DisplayName is the title to show for the node in client
// UIs. This field is assigned by default in controlclient,
// but can be overriden by providing this field non-empty
// in a MapResponse.
DisplayName string `json:",omitempty"`
// User is the user who created the node. If ACL tags are in // User is the user who created the node. If ACL tags are in
// use for the node then it doesn't reflect the ACL identity // use for the node then it doesn't reflect the ACL identity
// that the node is running as. // that the node is running as.
@ -185,6 +192,21 @@ type Node struct {
MachineAuthorized bool `json:",omitempty"` // TODO(crawshaw): replace with MachineStatus MachineAuthorized bool `json:",omitempty"` // TODO(crawshaw): replace with MachineStatus
} }
// DefaultDisplayName returns a value suitable
// for using as the default value for n.DisplayName.
func (n *Node) DefaultDisplayName() string {
if n.Name != "" {
// Use the Magic DNS prefix as the default display name.
return dnsname.ToBaseName(n.Name)
}
if n.Hostinfo.Hostname != "" {
// When no Magic DNS name is present, use the hostname.
return n.Hostinfo.Hostname
}
// When we've exhausted all other name options, use the node's ID.
return n.ID.String()
}
type MachineStatus int type MachineStatus int
const ( const (
@ -796,6 +818,7 @@ func (n *Node) Equal(n2 *Node) bool {
n.ID == n2.ID && n.ID == n2.ID &&
n.StableID == n2.StableID && n.StableID == n2.StableID &&
n.Name == n2.Name && n.Name == n2.Name &&
n.DisplayName == n2.DisplayName &&
n.User == n2.User && n.User == n2.User &&
n.Sharer == n2.Sharer && n.Sharer == n2.Sharer &&
n.Key == n2.Key && n.Key == n2.Key &&

@ -64,6 +64,7 @@ var _NodeNeedsRegeneration = Node(struct {
ID NodeID ID NodeID
StableID StableNodeID StableID StableNodeID
Name string Name string
DisplayName string
User UserID User UserID
Sharer UserID Sharer UserID
Key NodeKey Key NodeKey

@ -189,7 +189,7 @@ func TestHostinfoEqual(t *testing.T) {
func TestNodeEqual(t *testing.T) { func TestNodeEqual(t *testing.T) {
nodeHandles := []string{ nodeHandles := []string{
"ID", "StableID", "Name", "User", "Sharer", "ID", "StableID", "Name", "DisplayName", "User", "Sharer",
"Key", "KeyExpiry", "Machine", "DiscoKey", "Key", "KeyExpiry", "Machine", "DiscoKey",
"Addresses", "AllowedIPs", "Endpoints", "DERP", "Hostinfo", "Addresses", "AllowedIPs", "Endpoints", "DERP", "Hostinfo",
"Created", "LastSeen", "KeepAlive", "MachineAuthorized", "Created", "LastSeen", "KeepAlive", "MachineAuthorized",

@ -17,3 +17,11 @@ func HasSuffix(name, suffix string) bool {
nameBase := strings.TrimSuffix(name, suffix) nameBase := strings.TrimSuffix(name, suffix)
return len(nameBase) < len(name) && strings.HasSuffix(nameBase, ".") return len(nameBase) < len(name) && strings.HasSuffix(nameBase, ".")
} }
// ToBaseName removes the domain ending from a DNS name of a node.
func ToBaseName(name string) string {
if i := strings.Index(name, "."); i != -1 {
return name[:i]
}
return name
}

@ -26,3 +26,21 @@ func TestHasSuffix(t *testing.T) {
} }
} }
} }
func TestToBaseName(t *testing.T) {
tests := []struct {
name string
want string
}{
{"foo", "foo"},
{"foo.com", "foo"},
{"foo.example.com.beta.tailscale.net", "foo"},
{"computer-a.test.gmail.com.beta.tailscale.net", "computer-a"},
}
for _, tt := range tests {
got := ToBaseName(tt.name)
if got != tt.want {
t.Errorf("ToBaseName(%q) = %q; want %q", tt.name, got, tt.want)
}
}
}

Loading…
Cancel
Save