mirror of
https://github.com/netbirdio/netbird.git
synced 2026-06-19 06:19:54 +00:00
Compare commits
19 Commits
ui-refacto
...
fix/browse
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99dc3b0e7c | ||
|
|
023fc1023a | ||
|
|
4de804e128 | ||
|
|
0b3568bd78 | ||
|
|
bdcef5efbc | ||
|
|
bb6ee60d1b | ||
|
|
f6f071880d | ||
|
|
230ece1b7c | ||
|
|
8defb7944a | ||
|
|
fb188208ab | ||
|
|
12c2f63845 | ||
|
|
92ab202af9 | ||
|
|
600c27e727 | ||
|
|
0420842de7 | ||
|
|
df8fb9db8b | ||
|
|
6f3619ca11 | ||
|
|
1197857e34 | ||
|
|
ed8dcf598f | ||
|
|
ba4e455b1c |
@@ -982,7 +982,6 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync types.PeerSy
|
||||
var peer *nbpeer.Peer
|
||||
var updated, versionChanged, ipv6CapabilityChanged bool
|
||||
var err error
|
||||
var postureChecks []*posture.Checks
|
||||
var peerGroupIDs []string
|
||||
|
||||
settings, err := am.Store.GetAccountSettings(ctx, store.LockingStrengthNone, accountID)
|
||||
@@ -1025,11 +1024,6 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync types.PeerSy
|
||||
if err = transaction.SavePeer(ctx, accountID, peer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
postureChecks, err = getPeerPostureChecks(ctx, transaction, accountID, peer.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -1047,9 +1041,10 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync types.PeerSy
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
if isStatusChanged || sync.UpdateAccountPeers || ipv6CapabilityChanged || (updated && (len(postureChecks) > 0 || versionChanged)) {
|
||||
if isStatusChanged || sync.UpdateAccountPeers || ipv6CapabilityChanged || updated || versionChanged {
|
||||
changedPeerIDs := []string{peer.ID}
|
||||
affectedPeerIDs := am.syncPeerAffectedPeers(ctx, accountID, peer.ID, nmap, peerNotValid, updated, len(postureChecks) > 0)
|
||||
affectedPeerIDs := am.syncPeerAffectedPeers(ctx, accountID, peer.ID, nmap, peerNotValid, updated)
|
||||
log.Infof("Sync: peer %s affected peers %s", peer.ID, affectedPeerIDs)
|
||||
if err = am.networkMapController.OnPeersUpdated(ctx, accountID, changedPeerIDs, affectedPeerIDs); err != nil {
|
||||
return nil, nil, nil, 0, fmt.Errorf("notify network map controller of peer update: %w", err)
|
||||
}
|
||||
@@ -1066,8 +1061,8 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync types.PeerSy
|
||||
// metadata change that flips a posture result removes this peer from others'
|
||||
// maps asymmetrically; that case (and an invalid peer, whose map is empty) falls
|
||||
// back to the resolver.
|
||||
func (am *DefaultAccountManager) syncPeerAffectedPeers(ctx context.Context, accountID, peerID string, nmap *types.NetworkMap, peerNotValid, metaUpdated, hasPostureChecks bool) []string {
|
||||
if peerNotValid || (metaUpdated && hasPostureChecks) {
|
||||
func (am *DefaultAccountManager) syncPeerAffectedPeers(ctx context.Context, accountID, peerID string, nmap *types.NetworkMap, peerNotValid, metaUpdated bool) []string {
|
||||
if peerNotValid || metaUpdated {
|
||||
return am.resolveAffectedPeersForPeerChanges(ctx, am.Store, accountID, []string{peerID})
|
||||
}
|
||||
return affectedPeerIDsFromNetworkMap(nmap, peerID)
|
||||
@@ -1174,6 +1169,8 @@ func (am *DefaultAccountManager) LoginPeer(ctx context.Context, login types.Peer
|
||||
}
|
||||
}
|
||||
|
||||
peer.UpdateMetaIfNew(login.Meta)
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -1190,6 +1187,10 @@ func (am *DefaultAccountManager) LoginPeer(ctx context.Context, login types.Peer
|
||||
return nil, nil, nil, false, err
|
||||
}
|
||||
|
||||
changedPeerIDs := []string{peer.ID}
|
||||
affectedPeerIDs := am.resolveAffectedPeersForPeerChanges(ctx, am.Store, accountID, changedPeerIDs)
|
||||
log.Infof("Login: peer %s affected peers %s", peer.ID, affectedPeerIDs)
|
||||
|
||||
if isStatusChanged || shouldStorePeer {
|
||||
changedPeerIDs := []string{peer.ID}
|
||||
affectedPeerIDs := am.resolveAffectedPeersForPeerChanges(ctx, am.Store, accountID, changedPeerIDs)
|
||||
@@ -1291,12 +1292,12 @@ func getPeerLoginInfo(ctx context.Context, transaction store.Store, accountID st
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
enableSSH, err := isPeerSSHEnabled(ctx, transaction, accountID, peer)
|
||||
_, err = isPeerSSHEnabled(ctx, transaction, accountID, peer)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
return network, postureChecks, enableSSH, nil
|
||||
return network, postureChecks, true, nil
|
||||
}
|
||||
|
||||
func isPeerSSHEnabled(ctx context.Context, transaction store.Store, accountID string, peer *nbpeer.Peer) (bool, error) {
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/util"
|
||||
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||
)
|
||||
@@ -162,49 +166,7 @@ type PeerSystemMeta struct { //nolint:revive
|
||||
}
|
||||
|
||||
func (p PeerSystemMeta) isEqual(other PeerSystemMeta) bool {
|
||||
sort.Slice(p.NetworkAddresses, func(i, j int) bool {
|
||||
return p.NetworkAddresses[i].Mac < p.NetworkAddresses[j].Mac
|
||||
})
|
||||
sort.Slice(other.NetworkAddresses, func(i, j int) bool {
|
||||
return other.NetworkAddresses[i].Mac < other.NetworkAddresses[j].Mac
|
||||
})
|
||||
equalNetworkAddresses := slices.EqualFunc(p.NetworkAddresses, other.NetworkAddresses, func(addr NetworkAddress, oAddr NetworkAddress) bool {
|
||||
return addr.Mac == oAddr.Mac && addr.NetIP == oAddr.NetIP
|
||||
})
|
||||
if !equalNetworkAddresses {
|
||||
return false
|
||||
}
|
||||
|
||||
sort.Slice(p.Files, func(i, j int) bool {
|
||||
return p.Files[i].Path < p.Files[j].Path
|
||||
})
|
||||
sort.Slice(other.Files, func(i, j int) bool {
|
||||
return other.Files[i].Path < other.Files[j].Path
|
||||
})
|
||||
equalFiles := slices.EqualFunc(p.Files, other.Files, func(file File, oFile File) bool {
|
||||
return file.Path == oFile.Path && file.Exist == oFile.Exist && file.ProcessIsRunning == oFile.ProcessIsRunning
|
||||
})
|
||||
if !equalFiles {
|
||||
return false
|
||||
}
|
||||
|
||||
return p.Hostname == other.Hostname &&
|
||||
p.GoOS == other.GoOS &&
|
||||
p.Kernel == other.Kernel &&
|
||||
p.KernelVersion == other.KernelVersion &&
|
||||
p.Core == other.Core &&
|
||||
p.Platform == other.Platform &&
|
||||
p.OS == other.OS &&
|
||||
p.OSVersion == other.OSVersion &&
|
||||
p.WtVersion == other.WtVersion &&
|
||||
p.UIVersion == other.UIVersion &&
|
||||
p.SystemSerialNumber == other.SystemSerialNumber &&
|
||||
p.SystemProductName == other.SystemProductName &&
|
||||
p.SystemManufacturer == other.SystemManufacturer &&
|
||||
p.Environment.Cloud == other.Environment.Cloud &&
|
||||
p.Environment.Platform == other.Environment.Platform &&
|
||||
p.Flags.isEqual(other.Flags) &&
|
||||
capabilitiesEqual(p.Capabilities, other.Capabilities)
|
||||
return len(metaDiff(p, other)) == 0
|
||||
}
|
||||
|
||||
func (p PeerSystemMeta) isEmpty() bool {
|
||||
@@ -247,12 +209,12 @@ func (p *Peer) SupportsSourcePrefixes() bool {
|
||||
return p.HasCapability(PeerCapabilitySourcePrefixes)
|
||||
}
|
||||
|
||||
func capabilitiesEqual(a, b []int32) bool {
|
||||
if len(a) != len(b) {
|
||||
func (a PeerSystemMeta) CapabilitiesEqual(b []int32) bool {
|
||||
if len(a.Capabilities) != len(b) {
|
||||
return false
|
||||
}
|
||||
set := make(map[int32]struct{}, len(a))
|
||||
for _, c := range a {
|
||||
set := make(map[int32]struct{}, len(a.Capabilities))
|
||||
for _, c := range a.Capabilities {
|
||||
set[c] = struct{}{}
|
||||
}
|
||||
for _, c := range b {
|
||||
@@ -308,14 +270,113 @@ func (p *Peer) UpdateMetaIfNew(meta PeerSystemMeta) (updated, versionChanged boo
|
||||
meta.UIVersion = p.Meta.UIVersion
|
||||
}
|
||||
|
||||
if p.Meta.isEqual(meta) {
|
||||
return updated, versionChanged
|
||||
oldVersion := p.Meta.WtVersion
|
||||
|
||||
diff := metaDiff(p.Meta, meta)
|
||||
if len(diff) != 0 {
|
||||
p.Meta = meta
|
||||
updated = true
|
||||
}
|
||||
p.Meta = meta
|
||||
updated = true
|
||||
|
||||
versionInfo := ""
|
||||
if versionChanged {
|
||||
versionInfo = fmt.Sprintf("version changed: %s -> %s, ", oldVersion, meta.WtVersion)
|
||||
}
|
||||
|
||||
if versionChanged || updated {
|
||||
log.WithFields(log.Fields{"peer": p.ID, "key": p.Key}).
|
||||
Infof("peer meta updated, %s%d field(s) changed: %s", versionInfo, len(diff), strings.Join(diff, ", "))
|
||||
}
|
||||
|
||||
return updated, versionChanged
|
||||
}
|
||||
|
||||
// metaDiff returns a human-readable list of the fields that differ between the
|
||||
// old and new meta, each formatted as `field: <old> -> <new>`. It is the single
|
||||
// source of truth for meta comparison: isEqual reports equality as an empty
|
||||
// diff, so the log line can never disagree with the change decision. Slices are
|
||||
// cloned before sorting, so callers' meta is not mutated.
|
||||
func metaDiff(old, new PeerSystemMeta) []string {
|
||||
var diff []string
|
||||
add := func(field string, oldVal, newVal any) {
|
||||
diff = append(diff, fmt.Sprintf("%s: %v -> %v", field, oldVal, newVal))
|
||||
}
|
||||
|
||||
if old.Hostname != new.Hostname {
|
||||
add("hostname", old.Hostname, new.Hostname)
|
||||
}
|
||||
if old.GoOS != new.GoOS {
|
||||
add("goos", old.GoOS, new.GoOS)
|
||||
}
|
||||
if old.Kernel != new.Kernel {
|
||||
add("kernel", old.Kernel, new.Kernel)
|
||||
}
|
||||
if old.KernelVersion != new.KernelVersion {
|
||||
add("kernel_version", old.KernelVersion, new.KernelVersion)
|
||||
}
|
||||
if old.Core != new.Core {
|
||||
add("core", old.Core, new.Core)
|
||||
}
|
||||
if old.Platform != new.Platform {
|
||||
add("platform", old.Platform, new.Platform)
|
||||
}
|
||||
if old.OS != new.OS {
|
||||
add("os", old.OS, new.OS)
|
||||
}
|
||||
if old.OSVersion != new.OSVersion {
|
||||
add("os_version", old.OSVersion, new.OSVersion)
|
||||
}
|
||||
if old.WtVersion != new.WtVersion {
|
||||
add("wt_version", old.WtVersion, new.WtVersion)
|
||||
}
|
||||
if old.UIVersion != new.UIVersion {
|
||||
add("ui_version", old.UIVersion, new.UIVersion)
|
||||
}
|
||||
if old.SystemSerialNumber != new.SystemSerialNumber {
|
||||
add("system_serial_number", old.SystemSerialNumber, new.SystemSerialNumber)
|
||||
}
|
||||
if old.SystemProductName != new.SystemProductName {
|
||||
add("system_product_name", old.SystemProductName, new.SystemProductName)
|
||||
}
|
||||
if old.SystemManufacturer != new.SystemManufacturer {
|
||||
add("system_manufacturer", old.SystemManufacturer, new.SystemManufacturer)
|
||||
}
|
||||
if old.Environment.Cloud != new.Environment.Cloud {
|
||||
add("environment_cloud", old.Environment.Cloud, new.Environment.Cloud)
|
||||
}
|
||||
if old.Environment.Platform != new.Environment.Platform {
|
||||
add("environment_platform", old.Environment.Platform, new.Environment.Platform)
|
||||
}
|
||||
if !old.Flags.isEqual(new.Flags) {
|
||||
add("flags", fmt.Sprintf("%+v", old.Flags), fmt.Sprintf("%+v", new.Flags))
|
||||
}
|
||||
if !old.CapabilitiesEqual(new.Capabilities) {
|
||||
add("capabilities", old.Capabilities, new.Capabilities)
|
||||
}
|
||||
|
||||
oldAddrs := slices.Clone(old.NetworkAddresses)
|
||||
newAddrs := slices.Clone(new.NetworkAddresses)
|
||||
sort.Slice(oldAddrs, func(i, j int) bool { return oldAddrs[i].Mac < oldAddrs[j].Mac })
|
||||
sort.Slice(newAddrs, func(i, j int) bool { return newAddrs[i].Mac < newAddrs[j].Mac })
|
||||
if !slices.EqualFunc(oldAddrs, newAddrs, func(a, b NetworkAddress) bool {
|
||||
return a.Mac == b.Mac && a.NetIP == b.NetIP
|
||||
}) {
|
||||
add("network_addresses", fmt.Sprintf("%v", oldAddrs), fmt.Sprintf("%v", newAddrs))
|
||||
}
|
||||
|
||||
oldFiles := slices.Clone(old.Files)
|
||||
newFiles := slices.Clone(new.Files)
|
||||
sort.Slice(oldFiles, func(i, j int) bool { return oldFiles[i].Path < oldFiles[j].Path })
|
||||
sort.Slice(newFiles, func(i, j int) bool { return newFiles[i].Path < newFiles[j].Path })
|
||||
if !slices.EqualFunc(oldFiles, newFiles, func(a, b File) bool {
|
||||
return a.Path == b.Path && a.Exist == b.Exist && a.ProcessIsRunning == b.ProcessIsRunning
|
||||
}) {
|
||||
add("files", fmt.Sprintf("%v", oldFiles), fmt.Sprintf("%v", newFiles))
|
||||
}
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
// GetLastLogin returns the last login time of the peer.
|
||||
func (p *Peer) GetLastLogin() time.Time {
|
||||
if p.LastLogin != nil {
|
||||
|
||||
Reference in New Issue
Block a user