mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-23 10:05:19 +00:00
Changed DB objects and added migrations
This commit is contained in:
parent
ae03f440ee
commit
cf22604a4b
96
db.go
96
db.go
@ -43,49 +43,53 @@ func (h *Headscale) initDB() error {
|
|||||||
|
|
||||||
_ = db.Migrator().RenameTable("namespaces", "users")
|
_ = db.Migrator().RenameTable("namespaces", "users")
|
||||||
|
|
||||||
|
// the big rename from Machine to Node
|
||||||
|
_ = db.Migrator().RenameTable("machines", "nodes")
|
||||||
|
_ = db.Migrator().RenameColumn(&Route{}, "machine_id", "node_id")
|
||||||
|
|
||||||
err = db.AutoMigrate(&User{})
|
err = db.AutoMigrate(&User{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = db.Migrator().RenameColumn(&Machine{}, "namespace_id", "user_id")
|
_ = db.Migrator().RenameColumn(&Node{}, "namespace_id", "user_id")
|
||||||
_ = db.Migrator().RenameColumn(&PreAuthKey{}, "namespace_id", "user_id")
|
_ = db.Migrator().RenameColumn(&PreAuthKey{}, "namespace_id", "user_id")
|
||||||
|
|
||||||
_ = db.Migrator().RenameColumn(&Machine{}, "ip_address", "ip_addresses")
|
_ = db.Migrator().RenameColumn(&Node{}, "ip_address", "ip_addresses")
|
||||||
_ = db.Migrator().RenameColumn(&Machine{}, "name", "hostname")
|
_ = db.Migrator().RenameColumn(&Node{}, "name", "hostname")
|
||||||
|
|
||||||
// GivenName is used as the primary source of DNS names, make sure
|
// GivenName is used as the primary source of DNS names, make sure
|
||||||
// the field is populated and normalized if it was not when the
|
// the field is populated and normalized if it was not when the
|
||||||
// machine was registered.
|
// node was registered.
|
||||||
_ = db.Migrator().RenameColumn(&Machine{}, "nickname", "given_name")
|
_ = db.Migrator().RenameColumn(&Node{}, "nickname", "given_name")
|
||||||
|
|
||||||
// If the Machine table has a column for registered,
|
// If the Node table has a column for registered,
|
||||||
// find all occourences of "false" and drop them. Then
|
// find all occourences of "false" and drop them. Then
|
||||||
// remove the column.
|
// remove the column.
|
||||||
if db.Migrator().HasColumn(&Machine{}, "registered") {
|
if db.Migrator().HasColumn(&Node{}, "registered") {
|
||||||
log.Info().
|
log.Info().
|
||||||
Msg(`Database has legacy "registered" column in machine, removing...`)
|
Msg(`Database has legacy "registered" column in node, removing...`)
|
||||||
|
|
||||||
machines := Machines{}
|
nodes := Nodes{}
|
||||||
if err := h.db.Not("registered").Find(&machines).Error; err != nil {
|
if err := h.db.Not("registered").Find(&nodes).Error; err != nil {
|
||||||
log.Error().Err(err).Msg("Error accessing db")
|
log.Error().Err(err).Msg("Error accessing db")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, machine := range machines {
|
for _, node := range nodes {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("machine", machine.Hostname).
|
Str("node", node.Hostname).
|
||||||
Str("machine_key", machine.MachineKey).
|
Str("machine_key", node.MachineKey).
|
||||||
Msg("Deleting unregistered machine")
|
Msg("Deleting unregistered node")
|
||||||
if err := h.db.Delete(&Machine{}, machine.ID).Error; err != nil {
|
if err := h.db.Delete(&Node{}, node.ID).Error; err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
Err(err).
|
Err(err).
|
||||||
Str("machine", machine.Hostname).
|
Str("node", node.Hostname).
|
||||||
Str("machine_key", machine.MachineKey).
|
Str("machine_key", node.MachineKey).
|
||||||
Msg("Error deleting unregistered machine")
|
Msg("Error deleting unregistered node")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := db.Migrator().DropColumn(&Machine{}, "registered")
|
err := db.Migrator().DropColumn(&Node{}, "registered")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error dropping registered column")
|
log.Error().Err(err).Msg("Error dropping registered column")
|
||||||
}
|
}
|
||||||
@ -96,21 +100,21 @@ func (h *Headscale) initDB() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if db.Migrator().HasColumn(&Machine{}, "enabled_routes") {
|
if db.Migrator().HasColumn(&Node{}, "enabled_routes") {
|
||||||
log.Info().Msgf("Database has legacy enabled_routes column in machine, migrating...")
|
log.Info().Msgf("Database has legacy enabled_routes column in node, migrating...")
|
||||||
|
|
||||||
type MachineAux struct {
|
type NodeAux struct {
|
||||||
ID uint64
|
ID uint64
|
||||||
EnabledRoutes IPPrefixes
|
EnabledRoutes IPPrefixes
|
||||||
}
|
}
|
||||||
|
|
||||||
machinesAux := []MachineAux{}
|
nodesAux := []NodeAux{}
|
||||||
err := db.Table("machines").Select("id, enabled_routes").Scan(&machinesAux).Error
|
err := db.Table("nodes").Select("id, enabled_routes").Scan(&nodesAux).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Error accessing db")
|
log.Fatal().Err(err).Msg("Error accessing db")
|
||||||
}
|
}
|
||||||
for _, machine := range machinesAux {
|
for _, node := range nodesAux {
|
||||||
for _, prefix := range machine.EnabledRoutes {
|
for _, prefix := range node.EnabledRoutes {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
Err(err).
|
Err(err).
|
||||||
@ -120,8 +124,8 @@ func (h *Headscale) initDB() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Preload("Machine").
|
err = db.Preload("Node").
|
||||||
Where("machine_id = ? AND prefix = ?", machine.ID, IPPrefix(prefix)).
|
Where("node_id = ? AND prefix = ?", node.ID, IPPrefix(prefix)).
|
||||||
First(&Route{}).
|
First(&Route{}).
|
||||||
Error
|
Error
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -133,7 +137,7 @@ func (h *Headscale) initDB() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
route := Route{
|
route := Route{
|
||||||
MachineID: machine.ID,
|
NodeID: node.ID,
|
||||||
Advertised: true,
|
Advertised: true,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Prefix: IPPrefix(prefix),
|
Prefix: IPPrefix(prefix),
|
||||||
@ -142,51 +146,51 @@ func (h *Headscale) initDB() error {
|
|||||||
log.Error().Err(err).Msg("Error creating route")
|
log.Error().Err(err).Msg("Error creating route")
|
||||||
} else {
|
} else {
|
||||||
log.Info().
|
log.Info().
|
||||||
Uint64("machine_id", route.MachineID).
|
Uint64("node_id", route.NodeID).
|
||||||
Str("prefix", prefix.String()).
|
Str("prefix", prefix.String()).
|
||||||
Msg("Route migrated")
|
Msg("Route migrated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Migrator().DropColumn(&Machine{}, "enabled_routes")
|
err = db.Migrator().DropColumn(&Node{}, "enabled_routes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error dropping enabled_routes column")
|
log.Error().Err(err).Msg("Error dropping enabled_routes column")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.AutoMigrate(&Machine{})
|
err = db.AutoMigrate(&Node{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if db.Migrator().HasColumn(&Machine{}, "given_name") {
|
if db.Migrator().HasColumn(&Node{}, "given_name") {
|
||||||
machines := Machines{}
|
nodes := Nodes{}
|
||||||
if err := h.db.Find(&machines).Error; err != nil {
|
if err := h.db.Find(&nodes).Error; err != nil {
|
||||||
log.Error().Err(err).Msg("Error accessing db")
|
log.Error().Err(err).Msg("Error accessing db")
|
||||||
}
|
}
|
||||||
|
|
||||||
for item, machine := range machines {
|
for item, node := range nodes {
|
||||||
if machine.GivenName == "" {
|
if node.GivenName == "" {
|
||||||
normalizedHostname, err := NormalizeToFQDNRules(
|
normalizedHostname, err := NormalizeToFQDNRules(
|
||||||
machine.Hostname,
|
node.Hostname,
|
||||||
h.cfg.OIDC.StripEmaildomain,
|
h.cfg.OIDC.StripEmaildomain,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
Caller().
|
Caller().
|
||||||
Str("hostname", machine.Hostname).
|
Str("hostname", node.Hostname).
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Failed to normalize machine hostname in DB migration")
|
Msg("Failed to normalize node hostname in DB migration")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.RenameMachine(&machines[item], normalizedHostname)
|
err = h.RenameNode(&nodes[item], normalizedHostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
Caller().
|
Caller().
|
||||||
Str("hostname", machine.Hostname).
|
Str("hostname", node.Hostname).
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Failed to save normalized machine name in DB migration")
|
Msg("Failed to save normalized node name in DB migration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +328,7 @@ func (hi *HostInfo) Scan(destination interface{}) error {
|
|||||||
return json.Unmarshal([]byte(value), hi)
|
return json.Unmarshal([]byte(value), hi)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination)
|
return fmt.Errorf("%w: unexpected data type %T", ErrNodeAddressesInvalid, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +374,7 @@ func (i *IPPrefixes) Scan(destination interface{}) error {
|
|||||||
return json.Unmarshal([]byte(value), i)
|
return json.Unmarshal([]byte(value), i)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination)
|
return fmt.Errorf("%w: unexpected data type %T", ErrNodeAddressesInvalid, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +396,7 @@ func (i *StringList) Scan(destination interface{}) error {
|
|||||||
return json.Unmarshal([]byte(value), i)
|
return json.Unmarshal([]byte(value), i)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination)
|
return fmt.Errorf("%w: unexpected data type %T", ErrNodeAddressesInvalid, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
routes.go
78
routes.go
@ -23,9 +23,9 @@ var (
|
|||||||
type Route struct {
|
type Route struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
|
||||||
MachineID uint64
|
NodeID uint64
|
||||||
Machine Machine
|
Node Node
|
||||||
Prefix IPPrefix
|
Prefix IPPrefix
|
||||||
|
|
||||||
Advertised bool
|
Advertised bool
|
||||||
Enabled bool
|
Enabled bool
|
||||||
@ -35,7 +35,7 @@ type Route struct {
|
|||||||
type Routes []Route
|
type Routes []Route
|
||||||
|
|
||||||
func (r *Route) String() string {
|
func (r *Route) String() string {
|
||||||
return fmt.Sprintf("%s:%s", r.Machine, netip.Prefix(r.Prefix).String())
|
return fmt.Sprintf("%s:%s", r.Node, netip.Prefix(r.Prefix).String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) isExitRoute() bool {
|
func (r *Route) isExitRoute() bool {
|
||||||
@ -53,7 +53,7 @@ func (rs Routes) toPrefixes() []netip.Prefix {
|
|||||||
|
|
||||||
func (h *Headscale) GetRoutes() ([]Route, error) {
|
func (h *Headscale) GetRoutes() ([]Route, error) {
|
||||||
var routes []Route
|
var routes []Route
|
||||||
err := h.db.Preload("Machine").Find(&routes).Error
|
err := h.db.Preload("Node").Find(&routes).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -61,11 +61,11 @@ func (h *Headscale) GetRoutes() ([]Route, error) {
|
|||||||
return routes, nil
|
return routes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) GetMachineRoutes(m *Machine) ([]Route, error) {
|
func (h *Headscale) GetNodeRoutes(m *Node) ([]Route, error) {
|
||||||
var routes []Route
|
var routes []Route
|
||||||
err := h.db.
|
err := h.db.
|
||||||
Preload("Machine").
|
Preload("Node").
|
||||||
Where("machine_id = ?", m.ID).
|
Where("node_id = ?", m.ID).
|
||||||
Find(&routes).Error
|
Find(&routes).Error
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -76,7 +76,7 @@ func (h *Headscale) GetMachineRoutes(m *Machine) ([]Route, error) {
|
|||||||
|
|
||||||
func (h *Headscale) GetRoute(id uint64) (*Route, error) {
|
func (h *Headscale) GetRoute(id uint64) (*Route, error) {
|
||||||
var route Route
|
var route Route
|
||||||
err := h.db.Preload("Machine").First(&route, id).Error
|
err := h.db.Preload("Node").First(&route, id).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -94,10 +94,10 @@ func (h *Headscale) EnableRoute(id uint64) error {
|
|||||||
// be enabled at the same time, as per
|
// be enabled at the same time, as per
|
||||||
// https://github.com/juanfont/headscale/issues/804#issuecomment-1399314002
|
// https://github.com/juanfont/headscale/issues/804#issuecomment-1399314002
|
||||||
if route.isExitRoute() {
|
if route.isExitRoute() {
|
||||||
return h.enableRoutes(&route.Machine, ExitRouteV4.String(), ExitRouteV6.String())
|
return h.enableRoutes(&route.Node, ExitRouteV4.String(), ExitRouteV6.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.enableRoutes(&route.Machine, netip.Prefix(route.Prefix).String())
|
return h.enableRoutes(&route.Node, netip.Prefix(route.Prefix).String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) DisableRoute(id uint64) error {
|
func (h *Headscale) DisableRoute(id uint64) error {
|
||||||
@ -129,8 +129,8 @@ func (h *Headscale) DeleteRoute(id uint64) error {
|
|||||||
return h.handlePrimarySubnetFailover()
|
return h.handlePrimarySubnetFailover()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) DeleteMachineRoutes(m *Machine) error {
|
func (h *Headscale) DeleteNodeRoutes(node *Node) error {
|
||||||
routes, err := h.GetMachineRoutes(m)
|
routes, err := h.GetNodeRoutes(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -144,14 +144,14 @@ func (h *Headscale) DeleteMachineRoutes(m *Machine) error {
|
|||||||
return h.handlePrimarySubnetFailover()
|
return h.handlePrimarySubnetFailover()
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUniquePrefix returns if there is another machine providing the same route already.
|
// isUniquePrefix returns if there is another node providing the same route already.
|
||||||
func (h *Headscale) isUniquePrefix(route Route) bool {
|
func (h *Headscale) isUniquePrefix(route Route) bool {
|
||||||
var count int64
|
var count int64
|
||||||
h.db.
|
h.db.
|
||||||
Model(&Route{}).
|
Model(&Route{}).
|
||||||
Where("prefix = ? AND machine_id != ? AND advertised = ? AND enabled = ?",
|
Where("prefix = ? AND node_id != ? AND advertised = ? AND enabled = ?",
|
||||||
route.Prefix,
|
route.Prefix,
|
||||||
route.MachineID,
|
route.NodeID,
|
||||||
true, true).Count(&count)
|
true, true).Count(&count)
|
||||||
|
|
||||||
return count == 0
|
return count == 0
|
||||||
@ -160,7 +160,7 @@ func (h *Headscale) isUniquePrefix(route Route) bool {
|
|||||||
func (h *Headscale) getPrimaryRoute(prefix netip.Prefix) (*Route, error) {
|
func (h *Headscale) getPrimaryRoute(prefix netip.Prefix) (*Route, error) {
|
||||||
var route Route
|
var route Route
|
||||||
err := h.db.
|
err := h.db.
|
||||||
Preload("Machine").
|
Preload("Node").
|
||||||
Where("prefix = ? AND advertised = ? AND enabled = ? AND is_primary = ?", IPPrefix(prefix), true, true, true).
|
Where("prefix = ? AND advertised = ? AND enabled = ? AND is_primary = ?", IPPrefix(prefix), true, true, true).
|
||||||
First(&route).Error
|
First(&route).Error
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@ -174,13 +174,13 @@ func (h *Headscale) getPrimaryRoute(prefix netip.Prefix) (*Route, error) {
|
|||||||
return &route, nil
|
return &route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMachinePrimaryRoutes returns the routes that are enabled and marked as primary (for subnet failover)
|
// getNodePrimaryRoutes 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.
|
// Exit nodes are not considered for this, as they are never marked as Primary.
|
||||||
func (h *Headscale) getMachinePrimaryRoutes(m *Machine) ([]Route, error) {
|
func (h *Headscale) getNodePrimaryRoutes(m *Node) ([]Route, error) {
|
||||||
var routes []Route
|
var routes []Route
|
||||||
err := h.db.
|
err := h.db.
|
||||||
Preload("Machine").
|
Preload("Node").
|
||||||
Where("machine_id = ? AND advertised = ? AND enabled = ? AND is_primary = ?", m.ID, true, true, true).
|
Where("node_id = ? AND advertised = ? AND enabled = ? AND is_primary = ?", m.ID, true, true, true).
|
||||||
Find(&routes).Error
|
Find(&routes).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -189,15 +189,15 @@ func (h *Headscale) getMachinePrimaryRoutes(m *Machine) ([]Route, error) {
|
|||||||
return routes, nil
|
return routes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) processMachineRoutes(machine *Machine) error {
|
func (h *Headscale) processNodeRoutes(node *Node) error {
|
||||||
currentRoutes := []Route{}
|
currentRoutes := []Route{}
|
||||||
err := h.db.Where("machine_id = ?", machine.ID).Find(¤tRoutes).Error
|
err := h.db.Where("node_id = ?", node.ID).Find(¤tRoutes).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
advertisedRoutes := map[netip.Prefix]bool{}
|
advertisedRoutes := map[netip.Prefix]bool{}
|
||||||
for _, prefix := range machine.HostInfo.RoutableIPs {
|
for _, prefix := range node.HostInfo.RoutableIPs {
|
||||||
advertisedRoutes[prefix] = false
|
advertisedRoutes[prefix] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ func (h *Headscale) processMachineRoutes(machine *Machine) error {
|
|||||||
for prefix, exists := range advertisedRoutes {
|
for prefix, exists := range advertisedRoutes {
|
||||||
if !exists {
|
if !exists {
|
||||||
route := Route{
|
route := Route{
|
||||||
MachineID: machine.ID,
|
NodeID: node.ID,
|
||||||
Prefix: IPPrefix(prefix),
|
Prefix: IPPrefix(prefix),
|
||||||
Advertised: true,
|
Advertised: true,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
@ -243,7 +243,7 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
// first, get all the enabled routes
|
// first, get all the enabled routes
|
||||||
var routes []Route
|
var routes []Route
|
||||||
err := h.db.
|
err := h.db.
|
||||||
Preload("Machine").
|
Preload("Node").
|
||||||
Where("advertised = ? AND enabled = ?", true, true).
|
Where("advertised = ? AND enabled = ?", true, true).
|
||||||
Find(&routes).Error
|
Find(&routes).Error
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@ -261,7 +261,7 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
if h.isUniquePrefix(route) || errors.Is(err, gorm.ErrRecordNotFound) {
|
if h.isUniquePrefix(route) || errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("prefix", netip.Prefix(route.Prefix).String()).
|
Str("prefix", netip.Prefix(route.Prefix).String()).
|
||||||
Str("machine", route.Machine.GivenName).
|
Str("node", route.Node.GivenName).
|
||||||
Msg("Setting primary route")
|
Msg("Setting primary route")
|
||||||
routes[pos].IsPrimary = true
|
routes[pos].IsPrimary = true
|
||||||
err := h.db.Save(&routes[pos]).Error
|
err := h.db.Save(&routes[pos]).Error
|
||||||
@ -278,23 +278,23 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if route.IsPrimary {
|
if route.IsPrimary {
|
||||||
if route.Machine.isOnline() {
|
if route.Node.isOnline() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// machine offline, find a new primary
|
// node offline, find a new primary
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("machine", route.Machine.Hostname).
|
Str("node", route.Node.Hostname).
|
||||||
Str("prefix", netip.Prefix(route.Prefix).String()).
|
Str("prefix", netip.Prefix(route.Prefix).String()).
|
||||||
Msgf("machine offline, finding a new primary subnet")
|
Msgf("node offline, finding a new primary subnet")
|
||||||
|
|
||||||
// find a new primary route
|
// find a new primary route
|
||||||
var newPrimaryRoutes []Route
|
var newPrimaryRoutes []Route
|
||||||
err := h.db.
|
err := h.db.
|
||||||
Preload("Machine").
|
Preload("Node").
|
||||||
Where("prefix = ? AND machine_id != ? AND advertised = ? AND enabled = ?",
|
Where("prefix = ? AND node_id != ? AND advertised = ? AND enabled = ?",
|
||||||
route.Prefix,
|
route.Prefix,
|
||||||
route.MachineID,
|
route.NodeID,
|
||||||
true, true).
|
true, true).
|
||||||
Find(&newPrimaryRoutes).Error
|
Find(&newPrimaryRoutes).Error
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@ -305,7 +305,7 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
|
|
||||||
var newPrimaryRoute *Route
|
var newPrimaryRoute *Route
|
||||||
for pos, r := range newPrimaryRoutes {
|
for pos, r := range newPrimaryRoutes {
|
||||||
if r.Machine.isOnline() {
|
if r.Node.isOnline() {
|
||||||
newPrimaryRoute = &newPrimaryRoutes[pos]
|
newPrimaryRoute = &newPrimaryRoutes[pos]
|
||||||
|
|
||||||
break
|
break
|
||||||
@ -314,7 +314,7 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
|
|
||||||
if newPrimaryRoute == nil {
|
if newPrimaryRoute == nil {
|
||||||
log.Warn().
|
log.Warn().
|
||||||
Str("machine", route.Machine.Hostname).
|
Str("node", route.Node.Hostname).
|
||||||
Str("prefix", netip.Prefix(route.Prefix).String()).
|
Str("prefix", netip.Prefix(route.Prefix).String()).
|
||||||
Msgf("no alternative primary route found")
|
Msgf("no alternative primary route found")
|
||||||
|
|
||||||
@ -322,9 +322,9 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("old_machine", route.Machine.Hostname).
|
Str("old_node", route.Node.Hostname).
|
||||||
Str("prefix", netip.Prefix(route.Prefix).String()).
|
Str("prefix", netip.Prefix(route.Prefix).String()).
|
||||||
Str("new_machine", newPrimaryRoute.Machine.Hostname).
|
Str("new_node", newPrimaryRoute.Node.Hostname).
|
||||||
Msgf("found new primary route")
|
Msgf("found new primary route")
|
||||||
|
|
||||||
// disable the old primary route
|
// disable the old primary route
|
||||||
@ -362,7 +362,7 @@ func (rs Routes) toProto() []*v1.Route {
|
|||||||
for _, route := range rs {
|
for _, route := range rs {
|
||||||
protoRoute := v1.Route{
|
protoRoute := v1.Route{
|
||||||
Id: uint64(route.ID),
|
Id: uint64(route.ID),
|
||||||
Machine: route.Machine.toProto(),
|
Node: route.Node.toProto(),
|
||||||
Prefix: netip.Prefix(route.Prefix).String(),
|
Prefix: netip.Prefix(route.Prefix).String(),
|
||||||
Advertised: route.Advertised,
|
Advertised: route.Advertised,
|
||||||
Enabled: route.Enabled,
|
Enabled: route.Enabled,
|
||||||
|
Loading…
Reference in New Issue
Block a user