diff --git a/go.mod b/go.mod index bd1d01981..ed9c40b10 100644 --- a/go.mod +++ b/go.mod @@ -178,6 +178,7 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.15.0 // indirect + github.com/r3labs/diff v1.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect diff --git a/go.sum b/go.sum index 5e02e0d05..eeeeaa2af 100644 --- a/go.sum +++ b/go.sum @@ -415,6 +415,8 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/r3labs/diff v1.1.0 h1:V53xhrbTHrWFWq3gI4b94AjgEJOerO1+1l0xyHOBi8M= +github.com/r3labs/diff v1.1.0/go.mod h1:7WjXasNzi0vJetRcB/RqNl5dlIsmXcTTLmF5IoH6Xig= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= diff --git a/management/server/hash.go b/management/server/hash.go index a974a5087..f385f25c3 100644 --- a/management/server/hash.go +++ b/management/server/hash.go @@ -1,7 +1,7 @@ package server import ( - "github.com/mitchellh/hashstructure/v2" + "github.com/r3labs/diff" log "github.com/sirupsen/logrus" ) @@ -36,12 +36,12 @@ func updateAccountPeers(account *Account) { func updateAccountPeersWithHash(account *Account) { //start := time.Now() - var skipUpdate int - defer func() { - //duration := time.Since(start) - //log.Printf("Finished execution of updateAccountPeers, took %v\n", duration.Nanoseconds()) - //log.Println("not updated peers: ", skipUpdate) - }() + //var skipUpdate int + //defer func() { + // duration := time.Since(start) + // log.Printf("Finished execution of updateAccountPeers, took %v\n", duration.Nanoseconds()) + // log.Println("not updated peers: ", skipUpdate) + //}() peers := account.GetPeers() approvedPeersMap := make(map[string]struct{}, len(peers)) @@ -57,25 +57,39 @@ func updateAccountPeersWithHash(account *Account) { remotePeerNetworkMap := account.GetPeerNetworkMap(peer.ID, "netbird.io", approvedPeersMap) //log.Println("firewall rules: ", len(remotePeerNetworkMap.FirewallRules)) - hashStr, err := hashstructure.Hash(remotePeerNetworkMap, hashstructure.FormatV2, &hashstructure.HashOptions{ - ZeroNil: true, - IgnoreZeroValue: true, - SlicesAsSets: true, - UseStringer: true, - }) - if err != nil { - log.Errorf("failed to generate network map hash: %v", err) - } else { - if peer.NetworkMapHash == hashStr { - //log.Debugf("not sending network map update to peer: %s as there is nothing new", peer.ID) - skipUpdate++ - continue - } - peer.NetworkMapHash = hashStr - } + //hashStr, err := hashstructure.Hash(remotePeerNetworkMap, hashstructure.FormatV2, &hashstructure.HashOptions{ + // ZeroNil: true, + // IgnoreZeroValue: true, + // SlicesAsSets: true, + // UseStringer: true, + // //Hasher: xxhash.New(), + //}) + //if err != nil { + // log.Errorf("failed to generate network map hash: %v", err) + //} else { + // if peer.NetworkMapHash == hashStr { + // //log.Debugf("not sending network map update to peer: %s as there is nothing new", peer.ID) + // skipUpdate++ + // continue + // } + // peer.NetworkMapHash = hashStr + //} - //postureChecks := am.getPeerPostureChecks(account, peer) - //update := toSyncResponse(nil, peer, nil, remotePeerNetworkMap, am.GetDNSDomain(), postureChecks) - //am.peersUpdateManager.SendUpdate(peer.ID, &UpdateMessage{Update: update})update + if peer.NetworkMap == nil { + peer.NetworkMap = remotePeerNetworkMap + } else { + changelog, err := diff.Diff(peer.NetworkMap, remotePeerNetworkMap) + if err != nil { + log.Errorf("failed to generate network map diff: %v", err) + } else { + if len(changelog) == 0 { + continue + } + } + + } } } + +//48868101197 +// 8700718125 diff --git a/management/server/network.go b/management/server/network.go index 201b99a2d..91d844c3e 100644 --- a/management/server/network.go +++ b/management/server/network.go @@ -40,9 +40,9 @@ type Network struct { Dns string // Serial is an ID that increments by 1 when any change to the network happened (e.g. new peer has been added). // Used to synchronize state to the client apps. - Serial uint64 `hash:"ignore"` + Serial uint64 `diff:"-"` - mu sync.Mutex `json:"-" gorm:"-" hash:"ignore"` + mu sync.Mutex `json:"-" gorm:"-" diff:"-"` } // NewNetwork creates a new Network initializing it with a Serial=0 diff --git a/management/server/peer/peer.go b/management/server/peer/peer.go index 77c9397b3..4a71c28ee 100644 --- a/management/server/peer/peer.go +++ b/management/server/peer/peer.go @@ -18,37 +18,38 @@ type Peer struct { // WireGuard public key Key string `gorm:"index"` // A setup key this peer was registered with - SetupKey string + SetupKey string `diff:"-"` // IP address of the Peer IP net.IP `gorm:"serializer:json"` // Meta is a Peer system meta data - Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_"` + Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_" diff:"-"` // Name is peer's name (machine name) Name string // DNSLabel is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's // domain to the peer label. e.g. peer-dns-label.netbird.cloud DNSLabel string // Status peer's management connection status - Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_"` + Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_" diff:"-"` // The user ID that registered the peer - UserID string + UserID string `diff:"-"` // SSHKey is a public SSH key of the peer SSHKey string // SSHEnabled indicates whether SSH server is enabled on the peer SSHEnabled bool // LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login. // Works with LastLogin - LoginExpirationEnabled bool + LoginExpirationEnabled bool `diff:"-"` // LastLogin the time when peer performed last login operation - LastLogin time.Time + LastLogin time.Time `diff:"-"` // CreatedAt records the time the peer was created - CreatedAt time.Time + CreatedAt time.Time `diff:"-"` // Indicate ephemeral peer attribute - Ephemeral bool + Ephemeral bool `diff:"-"` // Geo location based on connection IP - Location Location `gorm:"embedded;embeddedPrefix:location_"` + Location Location `gorm:"embedded;embeddedPrefix:location_" diff:"-"` - NetworkMapHash uint64 `hash:"ignore"` + NetworkMap any `diff:"-"` + //NetworkMapHash uint64 `hash:"ignore"` } type PeerStatus struct { //nolint:revive