mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Validate isOutdated against all namespaces
This commit makes isOutdated validate a nodes necessity to update against all namespaces, and not just the nodes own namespace (which made more sense before). getLastStateChange is now uses the passed namespaces as a filter, meaning that not requesting any namespace will give you the total last updated state. In addition, the sync.Map is exchanged for a variant that uses generics which allows us to remove some casting logic.
This commit is contained in:
		
							parent
							
								
									a992840c9b
								
							
						
					
					
						commit
						a443255b3e
					
				
							
								
								
									
										24
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								app.go
									
									
									
									
									
								
							| @ -25,6 +25,7 @@ import ( | ||||
| 	v1 "github.com/juanfont/headscale/gen/go/headscale/v1" | ||||
| 	"github.com/patrickmn/go-cache" | ||||
| 	zerolog "github.com/philip-bui/grpc-zerolog" | ||||
| 	"github.com/puzpuzpuz/xsync" | ||||
| 	zl "github.com/rs/zerolog" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	ginprometheus "github.com/zsais/go-gin-prometheus" | ||||
| @ -160,7 +161,7 @@ type Headscale struct { | ||||
| 	aclPolicy *ACLPolicy | ||||
| 	aclRules  []tailcfg.FilterRule | ||||
| 
 | ||||
| 	lastStateChange sync.Map | ||||
| 	lastStateChange *xsync.MapOf[time.Time] | ||||
| 
 | ||||
| 	oidcProvider *oidc.Provider | ||||
| 	oauth2Config *oauth2.Config | ||||
| @ -793,18 +794,29 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { | ||||
| func (h *Headscale) setLastStateChangeToNow(namespace string) { | ||||
| 	now := time.Now().UTC() | ||||
| 	lastStateUpdate.WithLabelValues("", "headscale").Set(float64(now.Unix())) | ||||
| 	if h.lastStateChange == nil { | ||||
| 		h.lastStateChange = xsync.NewMapOf[time.Time]() | ||||
| 	} | ||||
| 	h.lastStateChange.Store(namespace, now) | ||||
| } | ||||
| 
 | ||||
| func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { | ||||
| 	times := []time.Time{} | ||||
| 
 | ||||
| 	for _, namespace := range namespaces { | ||||
| 		if wrapped, ok := h.lastStateChange.Load(namespace); ok { | ||||
| 			lastChange, _ := wrapped.(time.Time) | ||||
| 
 | ||||
| 			times = append(times, lastChange) | ||||
| 	// getLastStateChange takes a list of namespaces as a "filter", if no namespaces
 | ||||
| 	// are past, then use the entier list of namespaces and look for the last update
 | ||||
| 	if len(namespaces) > 0 { | ||||
| 		for _, namespace := range namespaces { | ||||
| 			if lastChange, ok := h.lastStateChange.Load(namespace); ok { | ||||
| 				times = append(times, lastChange) | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		h.lastStateChange.Range(func(key string, value time.Time) bool { | ||||
| 			times = append(times, value) | ||||
| 
 | ||||
| 			return true | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	sort.Slice(times, func(i, j int) bool { | ||||
|  | ||||
| @ -24,7 +24,7 @@ | ||||
| 
 | ||||
|               # When updating go.mod or go.sum, a new sha will need to be calculated, | ||||
|               # update this if you have a mismatch after doing a change to thos files. | ||||
|               vendorSha256 = "sha256-e3s10NsadWTEk7H7SbEvePhihJ1x2dS9UfIqPNIbJqI="; | ||||
|               vendorSha256 = "sha256-b6qPOO/NmcXsAsSRWZlYXZKyRAF++DsL4TEZzRhQhME="; | ||||
| 
 | ||||
|               ldflags = [ "-s" "-w" "-X github.com/juanfont/headscale/cmd/headscale/cli.Version=v${version}" ]; | ||||
|             }; | ||||
|  | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @ -115,6 +115,7 @@ require ( | ||||
| 	github.com/prometheus/client_model v0.2.0 // indirect | ||||
| 	github.com/prometheus/common v0.32.1 // indirect | ||||
| 	github.com/prometheus/procfs v0.7.3 // indirect | ||||
| 	github.com/puzpuzpuz/xsync v1.2.1 // indirect | ||||
| 	github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect | ||||
| 	github.com/rivo/uniseg v0.2.0 // indirect | ||||
| 	github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4 // indirect | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -478,6 +478,8 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b | ||||
| github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= | ||||
| github.com/pterm/pterm v0.12.41 h1:e2BRfFo1H9nL8GY0S3ImbZqfZ/YimOk9XtkhoobKJVs= | ||||
| github.com/pterm/pterm v0.12.41/go.mod h1:LW/G4J2A42XlTaPTAGRPvbBfF4UXvHWhC6SN7ueU4jU= | ||||
| github.com/puzpuzpuz/xsync v1.2.1 h1:faRb6HT9XN3IAhnE7IP0TnPpokPK42qFKXkhQVkWNwM= | ||||
| github.com/puzpuzpuz/xsync v1.2.1/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= | ||||
| github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= | ||||
| github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= | ||||
| github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | ||||
|  | ||||
							
								
								
									
										11
									
								
								machine.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								machine.go
									
									
									
									
									
								
							| @ -9,7 +9,6 @@ import ( | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	mapset "github.com/deckarep/golang-set/v2" | ||||
| 	v1 "github.com/juanfont/headscale/gen/go/headscale/v1" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"google.golang.org/protobuf/types/known/timestamppb" | ||||
| @ -469,10 +468,12 @@ func (h *Headscale) isOutdated(machine *Machine) bool { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	namespaceSet := mapset.NewSet[string]() | ||||
| 	namespaceSet.Add(machine.Namespace.Name) | ||||
| 
 | ||||
| 	lastChange := h.getLastStateChange(namespaceSet.ToSlice()...) | ||||
| 	// Get the last update from all headscale namespaces to compare with our nodes
 | ||||
| 	// last update.
 | ||||
| 	// TODO(kradalby): Only request updates from namespaces where we can talk to nodes
 | ||||
| 	// This would mostly be for a bit of performance, and can be calculated based on
 | ||||
| 	// ACLs.
 | ||||
| 	lastChange := h.getLastStateChange() | ||||
| 	lastUpdate := machine.CreatedAt | ||||
| 	if machine.LastSuccessfulUpdate != nil { | ||||
| 		lastUpdate = *machine.LastSuccessfulUpdate | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user