hscontrol: route hostname handling through dnsname and NodeStore
Ingest (registration and MapRequest updates) now calls dnsname.SanitizeHostname directly and lets NodeStore auto-bump on collision. Admin rename uses dnsname.ValidLabel + SetGivenName so conflicts are surfaced to the caller instead of silently mutated. Three duplicate invalidDNSRegex definitions, the old NormaliseHostname and ValidateHostname helpers, EnsureHostname, InvalidString, ApplyHostnameFromHostInfo, GivenNameHasBeenChanged, generateGivenName and EnsureUniqueGivenName are removed along with their tests. ValidateHostname's username half is retained as ValidateUsername for users.go. The SaaS-matching collision rule replaces the random "invalid-xxxxxx" fallback and the 8-character hash suffix; the empty-input fallback is the literal "node". TestUpdateHostnameFromClient now exercises the rewrite end-to-end with awkward macOS/Windows names. Fixes #3188 Fixes #2926 Fixes #2343 Fixes #2762 Fixes #2449 Updates #2177 Updates #2121 Updates #363
This commit is contained in:
parent
a2c3ac095e
commit
d6dfdc100c
15 changed files with 104 additions and 1707 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
|
|
@ -12,7 +11,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/cmpver"
|
||||
)
|
||||
|
||||
|
|
@ -282,44 +280,6 @@ func IsCI() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// EnsureHostname guarantees a valid hostname for node registration.
|
||||
// It extracts a hostname from Hostinfo, providing sensible defaults
|
||||
// if Hostinfo is nil or Hostname is empty. This prevents nil pointer dereferences
|
||||
// and ensures nodes always have a valid hostname.
|
||||
// The hostname is truncated to 63 characters to comply with DNS label length limits (RFC 1123).
|
||||
// This function never fails - it always returns a valid hostname.
|
||||
//
|
||||
// Strategy:
|
||||
// 1. If hostinfo is nil/empty → generate default from keys
|
||||
// 2. If hostname is provided → normalise it
|
||||
// 3. If normalisation fails → generate invalid-<random> replacement
|
||||
//
|
||||
// Returns the guaranteed-valid hostname to use.
|
||||
func EnsureHostname(hostinfo tailcfg.HostinfoView, machineKey, nodeKey string) string {
|
||||
if !hostinfo.Valid() || hostinfo.Hostname() == "" {
|
||||
key := cmp.Or(machineKey, nodeKey)
|
||||
if key == "" {
|
||||
return "unknown-node"
|
||||
}
|
||||
|
||||
keyPrefix := key
|
||||
if len(key) > 8 {
|
||||
keyPrefix = key[:8]
|
||||
}
|
||||
|
||||
return "node-" + keyPrefix
|
||||
}
|
||||
|
||||
lowercased := strings.ToLower(hostinfo.Hostname())
|
||||
|
||||
err := ValidateHostname(lowercased)
|
||||
if err == nil {
|
||||
return lowercased
|
||||
}
|
||||
|
||||
return InvalidString()
|
||||
}
|
||||
|
||||
// GenerateRegistrationKey generates a vanity key for tracking web authentication
|
||||
// registration flows in logs. This key is NOT stored in the database and does NOT use bcrypt -
|
||||
// it's purely for observability and correlating log entries during the registration process.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue