mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Cleanup route.go and add helper methods to process HostInfo
This commit is contained in:
		
							parent
							
								
									f4519cecf5
								
							
						
					
					
						commit
						552f4bf19b
					
				
							
								
								
									
										147
									
								
								routes.go
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								routes.go
									
									
									
									
									
								
							@ -23,109 +23,82 @@ type Route struct {
 | 
				
			|||||||
	IsPrimary  bool
 | 
						IsPrimary  bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Deprecated: use machine function instead
 | 
					type Routes []Route
 | 
				
			||||||
// GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by
 | 
					
 | 
				
			||||||
// namespace and node name).
 | 
					func (r *Route) String() string {
 | 
				
			||||||
func (h *Headscale) GetAdvertisedNodeRoutes(
 | 
						return fmt.Sprintf("%s:%s", r.Machine, netip.Prefix(r.Prefix).String())
 | 
				
			||||||
	namespace string,
 | 
					}
 | 
				
			||||||
	nodeName string,
 | 
					
 | 
				
			||||||
) (*[]netip.Prefix, error) {
 | 
					func (rs Routes) toPrefixes() []netip.Prefix {
 | 
				
			||||||
	machine, err := h.GetMachine(namespace, nodeName)
 | 
						prefixes := make([]netip.Prefix, len(rs))
 | 
				
			||||||
 | 
						for i, r := range rs {
 | 
				
			||||||
 | 
							prefixes[i] = netip.Prefix(r.Prefix)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return prefixes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getMachinePrimaryRoutes returns the routes that are enabled and marked as primary (for subnet failover)
 | 
				
			||||||
 | 
					// Exit nodes are not considered for this, as they are never marked as Primary
 | 
				
			||||||
 | 
					func (h *Headscale) getMachinePrimaryRoutes(m *Machine) ([]Route, error) {
 | 
				
			||||||
 | 
						var routes []Route
 | 
				
			||||||
 | 
						err := h.db.
 | 
				
			||||||
 | 
							Preload("Machine").
 | 
				
			||||||
 | 
							Where("machine_id = ? AND advertised = ? AND enabled = ? AND is_primary = ?", m.ID, true, true, true).
 | 
				
			||||||
 | 
							Find(&routes).Error
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &machine.HostInfo.RoutableIPs, nil
 | 
						return routes, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Deprecated: use machine function instead
 | 
					func (h *Headscale) processMachineRoutes(machine *Machine) error {
 | 
				
			||||||
// GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by
 | 
						currentRoutes := []Route{}
 | 
				
			||||||
// namespace and node name).
 | 
						err := h.db.Where("machine_id = ?", machine.ID).Find(¤tRoutes).Error
 | 
				
			||||||
func (h *Headscale) GetEnabledNodeRoutes(
 | 
					 | 
				
			||||||
	namespace string,
 | 
					 | 
				
			||||||
	nodeName string,
 | 
					 | 
				
			||||||
) ([]netip.Prefix, error) {
 | 
					 | 
				
			||||||
	machine, err := h.GetMachine(namespace, nodeName)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return machine.EnabledRoutes, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Deprecated: use machine function instead
 | 
					 | 
				
			||||||
// IsNodeRouteEnabled checks if a certain route has been enabled.
 | 
					 | 
				
			||||||
func (h *Headscale) IsNodeRouteEnabled(
 | 
					 | 
				
			||||||
	namespace string,
 | 
					 | 
				
			||||||
	nodeName string,
 | 
					 | 
				
			||||||
	routeStr string,
 | 
					 | 
				
			||||||
) bool {
 | 
					 | 
				
			||||||
	route, err := netip.ParsePrefix(routeStr)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	enabledRoutes, err := h.GetEnabledNodeRoutes(namespace, nodeName)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, enabledRoute := range enabledRoutes {
 | 
					 | 
				
			||||||
		if route == enabledRoute {
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Deprecated: use EnableRoute in machine.go
 | 
					 | 
				
			||||||
// EnableNodeRoute enables a subnet route advertised by a node (identified by
 | 
					 | 
				
			||||||
// namespace and node name).
 | 
					 | 
				
			||||||
func (h *Headscale) EnableNodeRoute(
 | 
					 | 
				
			||||||
	namespace string,
 | 
					 | 
				
			||||||
	nodeName string,
 | 
					 | 
				
			||||||
	routeStr string,
 | 
					 | 
				
			||||||
) error {
 | 
					 | 
				
			||||||
	machine, err := h.GetMachine(namespace, nodeName)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	route, err := netip.ParsePrefix(routeStr)
 | 
						advertisedRoutes := map[netip.Prefix]bool{}
 | 
				
			||||||
	if err != nil {
 | 
						for _, prefix := range machine.HostInfo.RoutableIPs {
 | 
				
			||||||
		return err
 | 
							advertisedRoutes[prefix] = false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	availableRoutes, err := h.GetAdvertisedNodeRoutes(namespace, nodeName)
 | 
						for _, route := range currentRoutes {
 | 
				
			||||||
	if err != nil {
 | 
							if _, ok := advertisedRoutes[netip.Prefix(route.Prefix)]; ok {
 | 
				
			||||||
		return err
 | 
								if !route.Advertised {
 | 
				
			||||||
	}
 | 
									route.Advertised = true
 | 
				
			||||||
 | 
									err := h.db.Save(&route).Error
 | 
				
			||||||
	enabledRoutes, err := h.GetEnabledNodeRoutes(namespace, nodeName)
 | 
									if err != nil {
 | 
				
			||||||
	if err != nil {
 | 
										return err
 | 
				
			||||||
		return err
 | 
									}
 | 
				
			||||||
	}
 | 
								}
 | 
				
			||||||
 | 
								advertisedRoutes[netip.Prefix(route.Prefix)] = true
 | 
				
			||||||
	available := false
 | 
							} else {
 | 
				
			||||||
	for _, availableRoute := range *availableRoutes {
 | 
								if route.Advertised {
 | 
				
			||||||
		// If the route is available, and not yet enabled, add it to the new routing table
 | 
									route.Advertised = false
 | 
				
			||||||
		if route == availableRoute {
 | 
									route.Enabled = false
 | 
				
			||||||
			available = true
 | 
									err := h.db.Save(&route).Error
 | 
				
			||||||
			if !h.IsNodeRouteEnabled(namespace, nodeName, routeStr) {
 | 
									if err != nil {
 | 
				
			||||||
				enabledRoutes = append(enabledRoutes, route)
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !available {
 | 
						for prefix, exists := range advertisedRoutes {
 | 
				
			||||||
		return ErrRouteIsNotAvailable
 | 
							if !exists {
 | 
				
			||||||
	}
 | 
								route := Route{
 | 
				
			||||||
 | 
									MachineID:  machine.ID,
 | 
				
			||||||
	machine.EnabledRoutes = enabledRoutes
 | 
									Prefix:     IPPrefix(prefix),
 | 
				
			||||||
 | 
									Advertised: true,
 | 
				
			||||||
	if err := h.db.Save(&machine).Error; err != nil {
 | 
									Enabled:    false,
 | 
				
			||||||
		return fmt.Errorf("failed to update node routes in the database: %w", err)
 | 
								}
 | 
				
			||||||
 | 
								err := h.db.Create(&route).Error
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user