mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-07 08:44:07 +01:00
[management] remove network map diff calculations (#2820)
This commit is contained in:
parent
ec5095ba6b
commit
4c758c6e52
3
go.mod
3
go.mod
@ -71,7 +71,6 @@ require (
|
|||||||
github.com/pion/transport/v3 v3.0.1
|
github.com/pion/transport/v3 v3.0.1
|
||||||
github.com/pion/turn/v3 v3.0.1
|
github.com/pion/turn/v3 v3.0.1
|
||||||
github.com/prometheus/client_golang v1.19.1
|
github.com/prometheus/client_golang v1.19.1
|
||||||
github.com/r3labs/diff/v3 v3.0.1
|
|
||||||
github.com/rs/xid v1.3.0
|
github.com/rs/xid v1.3.0
|
||||||
github.com/shirou/gopsutil/v3 v3.24.4
|
github.com/shirou/gopsutil/v3 v3.24.4
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||||
@ -211,8 +210,6 @@ require (
|
|||||||
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
||||||
github.com/tklauser/numcpus v0.8.0 // indirect
|
github.com/tklauser/numcpus v0.8.0 // indirect
|
||||||
github.com/vishvananda/netns v0.0.4 // indirect
|
github.com/vishvananda/netns v0.0.4 // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
|
||||||
github.com/yuin/goldmark v1.7.1 // indirect
|
github.com/yuin/goldmark v1.7.1 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -605,8 +605,6 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a
|
|||||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
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 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek=
|
||||||
github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk=
|
github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk=
|
||||||
github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg=
|
|
||||||
github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo=
|
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
@ -699,10 +697,6 @@ github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhg
|
|||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
package differs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/netip"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/r3labs/diff/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NetIPAddr is a custom differ for netip.Addr
|
|
||||||
type NetIPAddr struct {
|
|
||||||
DiffFunc func(path []string, a, b reflect.Value, p interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPAddr) Match(a, b reflect.Value) bool {
|
|
||||||
return diff.AreType(a, b, reflect.TypeOf(netip.Addr{}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPAddr) Diff(_ diff.DiffType, _ diff.DiffFunc, cl *diff.Changelog, path []string, a, b reflect.Value, _ interface{}) error {
|
|
||||||
if a.Kind() == reflect.Invalid {
|
|
||||||
cl.Add(diff.CREATE, path, nil, b.Interface())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.Kind() == reflect.Invalid {
|
|
||||||
cl.Add(diff.DELETE, path, a.Interface(), nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fromAddr, ok1 := a.Interface().(netip.Addr)
|
|
||||||
toAddr, ok2 := b.Interface().(netip.Addr)
|
|
||||||
if !ok1 || !ok2 {
|
|
||||||
return fmt.Errorf("invalid type for netip.Addr")
|
|
||||||
}
|
|
||||||
|
|
||||||
if fromAddr.String() != toAddr.String() {
|
|
||||||
cl.Add(diff.UPDATE, path, fromAddr.String(), toAddr.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPAddr) InsertParentDiffer(dfunc func(path []string, a, b reflect.Value, p interface{}) error) {
|
|
||||||
differ.DiffFunc = dfunc //nolint
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetIPPrefix is a custom differ for netip.Prefix
|
|
||||||
type NetIPPrefix struct {
|
|
||||||
DiffFunc func(path []string, a, b reflect.Value, p interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPPrefix) Match(a, b reflect.Value) bool {
|
|
||||||
return diff.AreType(a, b, reflect.TypeOf(netip.Prefix{}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPPrefix) Diff(_ diff.DiffType, _ diff.DiffFunc, cl *diff.Changelog, path []string, a, b reflect.Value, _ interface{}) error {
|
|
||||||
if a.Kind() == reflect.Invalid {
|
|
||||||
cl.Add(diff.CREATE, path, nil, b.Interface())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if b.Kind() == reflect.Invalid {
|
|
||||||
cl.Add(diff.DELETE, path, a.Interface(), nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fromPrefix, ok1 := a.Interface().(netip.Prefix)
|
|
||||||
toPrefix, ok2 := b.Interface().(netip.Prefix)
|
|
||||||
if !ok1 || !ok2 {
|
|
||||||
return fmt.Errorf("invalid type for netip.Addr")
|
|
||||||
}
|
|
||||||
|
|
||||||
if fromPrefix.String() != toPrefix.String() {
|
|
||||||
cl.Add(diff.UPDATE, path, fromPrefix.String(), toPrefix.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (differ NetIPPrefix) InsertParentDiffer(dfunc func(path []string, a, b reflect.Value, p interface{}) error) {
|
|
||||||
differ.DiffFunc = dfunc //nolint
|
|
||||||
}
|
|
@ -8,9 +8,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
nbdns "github.com/netbirdio/netbird/dns"
|
nbdns "github.com/netbirdio/netbird/dns"
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
@ -521,6 +522,34 @@ func TestDNSAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Creating DNS settings with groups that have no peers should not update account peers or send peer update
|
||||||
|
t.Run("creating dns setting with unused groups", func(t *testing.T) {
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
peerShouldNotReceiveUpdate(t, updMsg)
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = manager.CreateNameServerGroup(
|
||||||
|
context.Background(), account.Id, "ns-group", "ns-group", []dns.NameServer{{
|
||||||
|
IP: netip.MustParseAddr(peer1.IP.String()),
|
||||||
|
NSType: dns.UDPNameServerType,
|
||||||
|
Port: dns.DefaultDNSPort,
|
||||||
|
}},
|
||||||
|
[]string{"groupB"},
|
||||||
|
true, []string{}, true, userID, false,
|
||||||
|
)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Creating DNS settings with groups that have peers should update account peers and send peer update
|
||||||
|
t.Run("creating dns setting with used groups", func(t *testing.T) {
|
||||||
err = manager.SaveGroup(context.Background(), account.Id, userID, &group.Group{
|
err = manager.SaveGroup(context.Background(), account.Id, userID, &group.Group{
|
||||||
ID: "groupA",
|
ID: "groupA",
|
||||||
Name: "GroupA",
|
Name: "GroupA",
|
||||||
@ -528,6 +557,12 @@ func TestDNSAccountPeersUpdate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
_, err = manager.CreateNameServerGroup(
|
_, err = manager.CreateNameServerGroup(
|
||||||
context.Background(), account.Id, "ns-group-1", "ns-group-1", []dns.NameServer{{
|
context.Background(), account.Id, "ns-group-1", "ns-group-1", []dns.NameServer{{
|
||||||
IP: netip.MustParseAddr(peer1.IP.String()),
|
IP: netip.MustParseAddr(peer1.IP.String()),
|
||||||
@ -539,6 +574,13 @@ func TestDNSAccountPeersUpdate(t *testing.T) {
|
|||||||
)
|
)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Error("timeout waiting for peerShouldReceiveUpdate")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Saving DNS settings with groups that have peers should update account peers and send peer update
|
// Saving DNS settings with groups that have peers should update account peers and send peer update
|
||||||
t.Run("saving dns setting with used groups", func(t *testing.T) {
|
t.Run("saving dns setting with used groups", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
@ -559,27 +601,6 @@ func TestDNSAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Saving unchanged DNS settings with used groups should update account peers and not send peer update
|
|
||||||
// since there is no change in the network map
|
|
||||||
t.Run("saving unchanged dns setting with used groups", func(t *testing.T) {
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := manager.SaveDNSSettings(context.Background(), account.Id, userID, &DNSSettings{
|
|
||||||
DisabledManagementGroups: []string{"groupA", "groupB"},
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Removing group with no peers from DNS settings should not trigger updates to account peers or send peer updates
|
// Removing group with no peers from DNS settings should not trigger updates to account peers or send peer updates
|
||||||
t.Run("removing group with no peers from dns settings", func(t *testing.T) {
|
t.Run("removing group with no peers from dns settings", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
@ -8,12 +8,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
nbdns "github.com/netbirdio/netbird/dns"
|
nbdns "github.com/netbirdio/netbird/dns"
|
||||||
nbgroup "github.com/netbirdio/netbird/management/server/group"
|
nbgroup "github.com/netbirdio/netbird/management/server/group"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -536,29 +537,6 @@ func TestGroupAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Saving an unchanged group should trigger account peers update and not send peer update
|
|
||||||
// since there is no change in the network map
|
|
||||||
t.Run("saving unchanged group", func(t *testing.T) {
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
|
|
||||||
ID: "groupA",
|
|
||||||
Name: "GroupA",
|
|
||||||
Peers: []string{peer1.ID, peer2.ID},
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// adding peer to a used group should update account peers and send peer update
|
// adding peer to a used group should update account peers and send peer update
|
||||||
t.Run("adding peer to linked group", func(t *testing.T) {
|
t.Run("adding peer to linked group", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
@ -1065,36 +1065,6 @@ func TestNameServerAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// saving unchanged nameserver group should update account peers and not send peer update
|
|
||||||
t.Run("saving unchanged nameserver group", func(t *testing.T) {
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
newNameServerGroupB.NameServers = []nbdns.NameServer{
|
|
||||||
{
|
|
||||||
IP: netip.MustParseAddr("1.1.1.2"),
|
|
||||||
NSType: nbdns.UDPNameServerType,
|
|
||||||
Port: nbdns.DefaultDNSPort,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
IP: netip.MustParseAddr("8.8.8.8"),
|
|
||||||
NSType: nbdns.UDPNameServerType,
|
|
||||||
Port: nbdns.DefaultDNSPort,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err = manager.SaveNameServerGroup(context.Background(), account.Id, userID, newNameServerGroupB)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Deleting a nameserver group should update account peers and send peer update
|
// Deleting a nameserver group should update account peers and send peer update
|
||||||
t.Run("deleting nameserver group", func(t *testing.T) {
|
t.Run("deleting nameserver group", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
@ -41,9 +41,9 @@ type Network struct {
|
|||||||
Dns string
|
Dns string
|
||||||
// Serial is an ID that increments by 1 when any change to the network happened (e.g. new peer has been added).
|
// 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.
|
// Used to synchronize state to the client apps.
|
||||||
Serial uint64 `diff:"-"`
|
Serial uint64
|
||||||
|
|
||||||
mu sync.Mutex `json:"-" gorm:"-" diff:"-"`
|
mu sync.Mutex `json:"-" gorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNetwork creates a new Network initializing it with a Serial=0
|
// NewNetwork creates a new Network initializing it with a Serial=0
|
||||||
|
@ -20,33 +20,33 @@ type Peer struct {
|
|||||||
// IP address of the Peer
|
// IP address of the Peer
|
||||||
IP net.IP `gorm:"serializer:json"`
|
IP net.IP `gorm:"serializer:json"`
|
||||||
// Meta is a Peer system meta data
|
// Meta is a Peer system meta data
|
||||||
Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_" diff:"-"`
|
Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_"`
|
||||||
// Name is peer's name (machine name)
|
// Name is peer's name (machine name)
|
||||||
Name string
|
Name string
|
||||||
// DNSLabel is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's
|
// 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
|
// domain to the peer label. e.g. peer-dns-label.netbird.cloud
|
||||||
DNSLabel string
|
DNSLabel string
|
||||||
// Status peer's management connection status
|
// Status peer's management connection status
|
||||||
Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_" diff:"-"`
|
Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_"`
|
||||||
// The user ID that registered the peer
|
// The user ID that registered the peer
|
||||||
UserID string `diff:"-"`
|
UserID string
|
||||||
// SSHKey is a public SSH key of the peer
|
// SSHKey is a public SSH key of the peer
|
||||||
SSHKey string
|
SSHKey string
|
||||||
// SSHEnabled indicates whether SSH server is enabled on the peer
|
// SSHEnabled indicates whether SSH server is enabled on the peer
|
||||||
SSHEnabled bool
|
SSHEnabled bool
|
||||||
// LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login.
|
// LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login.
|
||||||
// Works with LastLogin
|
// Works with LastLogin
|
||||||
LoginExpirationEnabled bool `diff:"-"`
|
LoginExpirationEnabled bool
|
||||||
|
|
||||||
InactivityExpirationEnabled bool `diff:"-"`
|
InactivityExpirationEnabled bool
|
||||||
// LastLogin the time when peer performed last login operation
|
// LastLogin the time when peer performed last login operation
|
||||||
LastLogin time.Time `diff:"-"`
|
LastLogin time.Time
|
||||||
// CreatedAt records the time the peer was created
|
// CreatedAt records the time the peer was created
|
||||||
CreatedAt time.Time `diff:"-"`
|
CreatedAt time.Time
|
||||||
// Indicate ephemeral peer attribute
|
// Indicate ephemeral peer attribute
|
||||||
Ephemeral bool `diff:"-"`
|
Ephemeral bool
|
||||||
// Geo location based on connection IP
|
// Geo location based on connection IP
|
||||||
Location Location `gorm:"embedded;embeddedPrefix:location_" diff:"-"`
|
Location Location `gorm:"embedded;embeddedPrefix:location_"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PeerStatus struct { //nolint:revive
|
type PeerStatus struct { //nolint:revive
|
||||||
|
@ -405,7 +405,9 @@ func (am *DefaultAccountManager) DeletePolicy(ctx context.Context, accountID, po
|
|||||||
|
|
||||||
am.StoreEvent(ctx, userID, policy.ID, accountID, activity.PolicyRemoved, policy.EventMeta())
|
am.StoreEvent(ctx, userID, policy.ID, accountID, activity.PolicyRemoved, policy.EventMeta())
|
||||||
|
|
||||||
|
if anyGroupHasPeers(account, policy.ruleGroups()) {
|
||||||
am.updateAccountPeers(ctx, account)
|
am.updateAccountPeers(ctx, account)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -854,16 +854,11 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
updMsg1 := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
|
updMsg := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)
|
manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
updMsg2 := manager.peersUpdateManager.CreateChannel(context.Background(), peer2.ID)
|
|
||||||
t.Cleanup(func() {
|
|
||||||
manager.peersUpdateManager.CloseChannel(context.Background(), peer2.ID)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Saving policy with rule groups with no peers should not update account's peers and not send peer update
|
// Saving policy with rule groups with no peers should not update account's peers and not send peer update
|
||||||
t.Run("saving policy with rule groups with no peers", func(t *testing.T) {
|
t.Run("saving policy with rule groups with no peers", func(t *testing.T) {
|
||||||
policy := Policy{
|
policy := Policy{
|
||||||
@ -883,7 +878,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldNotReceiveUpdate(t, updMsg1)
|
peerShouldNotReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -918,7 +913,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg1)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -953,7 +948,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg2)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -987,7 +982,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg1)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1021,7 +1016,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg1)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1056,7 +1051,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldNotReceiveUpdate(t, updMsg1)
|
peerShouldNotReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1090,7 +1085,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg1)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1104,46 +1099,13 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Saving unchanged policy should trigger account peers update but not send peer update
|
|
||||||
t.Run("saving unchanged policy", func(t *testing.T) {
|
|
||||||
policy := Policy{
|
|
||||||
ID: "policy-source-destination-peers",
|
|
||||||
Enabled: true,
|
|
||||||
Rules: []*PolicyRule{
|
|
||||||
{
|
|
||||||
ID: xid.New().String(),
|
|
||||||
Enabled: true,
|
|
||||||
Sources: []string{"groupA"},
|
|
||||||
Destinations: []string{"groupD"},
|
|
||||||
Bidirectional: true,
|
|
||||||
Action: PolicyTrafficActionAccept,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg1)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, true)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Deleting policy should trigger account peers update and send peer update
|
// Deleting policy should trigger account peers update and send peer update
|
||||||
t.Run("deleting policy with source and destination groups with peers", func(t *testing.T) {
|
t.Run("deleting policy with source and destination groups with peers", func(t *testing.T) {
|
||||||
policyID := "policy-source-destination-peers"
|
policyID := "policy-source-destination-peers"
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg1)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1164,7 +1126,7 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
policyID := "policy-destination-has-peers-source-none"
|
policyID := "policy-destination-has-peers-source-none"
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldReceiveUpdate(t, updMsg2)
|
peerShouldReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -1180,10 +1142,10 @@ func TestPolicyAccountPeersUpdate(t *testing.T) {
|
|||||||
|
|
||||||
// Deleting policy with no peers in groups should not update account's peers and not send peer update
|
// Deleting policy with no peers in groups should not update account's peers and not send peer update
|
||||||
t.Run("deleting policy with no peers in groups", func(t *testing.T) {
|
t.Run("deleting policy with no peers in groups", func(t *testing.T) {
|
||||||
policyID := "policy-rule-groups-no-peers" // Deleting the policy created in Case 2
|
policyID := "policy-rule-groups-no-peers"
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
peerShouldNotReceiveUpdate(t, updMsg1)
|
peerShouldNotReceiveUpdate(t, updMsg)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -5,10 +5,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/group"
|
|
||||||
"github.com/rs/xid"
|
"github.com/rs/xid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/management/server/group"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/posture"
|
"github.com/netbirdio/netbird/management/server/posture"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -264,25 +265,6 @@ func TestPostureCheckAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Saving unchanged posture check should not trigger account peers update and not send peer update
|
|
||||||
// since there is no change in the network map
|
|
||||||
t.Run("saving unchanged posture check", func(t *testing.T) {
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := manager.SavePostureChecks(context.Background(), account.Id, userID, &postureCheck)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Removing posture check from policy should trigger account peers update and send peer update
|
// Removing posture check from policy should trigger account peers update and send peer update
|
||||||
t.Run("removing posture check from policy", func(t *testing.T) {
|
t.Run("removing posture check from policy", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
@ -412,50 +394,9 @@ func TestPostureCheckAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Updating linked posture check to policy where source has peers but destination does not,
|
|
||||||
// should not trigger account peers update or send peer update
|
|
||||||
t.Run("updating linked posture check to policy where source has peers but destination does not", func(t *testing.T) {
|
|
||||||
policy = Policy{
|
|
||||||
ID: "policyB",
|
|
||||||
Enabled: true,
|
|
||||||
Rules: []*PolicyRule{
|
|
||||||
{
|
|
||||||
Enabled: true,
|
|
||||||
Sources: []string{"groupA"},
|
|
||||||
Destinations: []string{"groupB"},
|
|
||||||
Bidirectional: true,
|
|
||||||
Action: PolicyTrafficActionAccept,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SourcePostureChecks: []string{postureCheck.ID},
|
|
||||||
}
|
|
||||||
err = manager.SavePolicy(context.Background(), account.Id, userID, &policy, true)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
postureCheck.Checks = posture.ChecksDefinition{
|
|
||||||
NBVersionCheck: &posture.NBVersionCheck{
|
|
||||||
MinVersion: "0.29.0",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := manager.SavePostureChecks(context.Background(), account.Id, userID, &postureCheck)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Updating linked client posture check to policy where source has peers but destination does not,
|
// Updating linked client posture check to policy where source has peers but destination does not,
|
||||||
// should trigger account peers update and send peer update
|
// should trigger account peers update and send peer update
|
||||||
t.Run("updating linked client posture check to policy where source has peers but destination does not", func(t *testing.T) {
|
t.Run("updating linked posture check to policy where source has peers but destination does not", func(t *testing.T) {
|
||||||
policy = Policy{
|
policy = Policy{
|
||||||
ID: "policyB",
|
ID: "policyB",
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
@ -1938,26 +1938,6 @@ func TestRouteAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Updating unchanged route should update account peers and not send peer update
|
|
||||||
t.Run("updating unchanged route", func(t *testing.T) {
|
|
||||||
baseRoute.Groups = []string{routeGroup1, routeGroup2}
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
peerShouldNotReceiveUpdate(t, updMsg)
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := manager.SaveRoute(context.Background(), account.Id, userID, &baseRoute)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Deleting the route should update account peers and send peer update
|
// Deleting the route should update account peers and send peer update
|
||||||
t.Run("deleting route", func(t *testing.T) {
|
t.Run("deleting route", func(t *testing.T) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
@ -18,7 +18,6 @@ type UpdateChannelMetrics struct {
|
|||||||
getAllConnectedPeersDurationMicro metric.Int64Histogram
|
getAllConnectedPeersDurationMicro metric.Int64Histogram
|
||||||
getAllConnectedPeers metric.Int64Histogram
|
getAllConnectedPeers metric.Int64Histogram
|
||||||
hasChannelDurationMicro metric.Int64Histogram
|
hasChannelDurationMicro metric.Int64Histogram
|
||||||
networkMapDiffDurationMicro metric.Int64Histogram
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +63,6 @@ func NewUpdateChannelMetrics(ctx context.Context, meter metric.Meter) (*UpdateCh
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
networkMapDiffDurationMicro, err := meter.Int64Histogram("management.updatechannel.networkmap.diff.duration.micro")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &UpdateChannelMetrics{
|
return &UpdateChannelMetrics{
|
||||||
createChannelDurationMicro: createChannelDurationMicro,
|
createChannelDurationMicro: createChannelDurationMicro,
|
||||||
closeChannelDurationMicro: closeChannelDurationMicro,
|
closeChannelDurationMicro: closeChannelDurationMicro,
|
||||||
@ -78,7 +72,6 @@ func NewUpdateChannelMetrics(ctx context.Context, meter metric.Meter) (*UpdateCh
|
|||||||
getAllConnectedPeersDurationMicro: getAllConnectedPeersDurationMicro,
|
getAllConnectedPeersDurationMicro: getAllConnectedPeersDurationMicro,
|
||||||
getAllConnectedPeers: getAllConnectedPeers,
|
getAllConnectedPeers: getAllConnectedPeers,
|
||||||
hasChannelDurationMicro: hasChannelDurationMicro,
|
hasChannelDurationMicro: hasChannelDurationMicro,
|
||||||
networkMapDiffDurationMicro: networkMapDiffDurationMicro,
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -118,8 +111,3 @@ func (metrics *UpdateChannelMetrics) CountGetAllConnectedPeersDuration(duration
|
|||||||
func (metrics *UpdateChannelMetrics) CountHasChannelDuration(duration time.Duration) {
|
func (metrics *UpdateChannelMetrics) CountHasChannelDuration(duration time.Duration) {
|
||||||
metrics.hasChannelDurationMicro.Record(metrics.ctx, duration.Microseconds())
|
metrics.hasChannelDurationMicro.Record(metrics.ctx, duration.Microseconds())
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountNetworkMapDiffDurationMicro counts the duration of the NetworkMapDiff method
|
|
||||||
func (metrics *UpdateChannelMetrics) CountNetworkMapDiffDurationMicro(duration time.Duration) {
|
|
||||||
metrics.networkMapDiffDurationMicro.Record(metrics.ctx, duration.Microseconds())
|
|
||||||
}
|
|
||||||
|
@ -2,16 +2,12 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"runtime/debug"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/r3labs/diff/v3"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/proto"
|
"github.com/netbirdio/netbird/management/proto"
|
||||||
"github.com/netbirdio/netbird/management/server/differs"
|
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,8 +21,6 @@ type UpdateMessage struct {
|
|||||||
type PeersUpdateManager struct {
|
type PeersUpdateManager struct {
|
||||||
// peerChannels is an update channel indexed by Peer.ID
|
// peerChannels is an update channel indexed by Peer.ID
|
||||||
peerChannels map[string]chan *UpdateMessage
|
peerChannels map[string]chan *UpdateMessage
|
||||||
// peerNetworkMaps is the UpdateMessage indexed by Peer.ID.
|
|
||||||
peerUpdateMessage map[string]*UpdateMessage
|
|
||||||
// channelsMux keeps the mutex to access peerChannels
|
// channelsMux keeps the mutex to access peerChannels
|
||||||
channelsMux *sync.RWMutex
|
channelsMux *sync.RWMutex
|
||||||
// metrics provides method to collect application metrics
|
// metrics provides method to collect application metrics
|
||||||
@ -37,7 +31,6 @@ type PeersUpdateManager struct {
|
|||||||
func NewPeersUpdateManager(metrics telemetry.AppMetrics) *PeersUpdateManager {
|
func NewPeersUpdateManager(metrics telemetry.AppMetrics) *PeersUpdateManager {
|
||||||
return &PeersUpdateManager{
|
return &PeersUpdateManager{
|
||||||
peerChannels: make(map[string]chan *UpdateMessage),
|
peerChannels: make(map[string]chan *UpdateMessage),
|
||||||
peerUpdateMessage: make(map[string]*UpdateMessage),
|
|
||||||
channelsMux: &sync.RWMutex{},
|
channelsMux: &sync.RWMutex{},
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
}
|
}
|
||||||
@ -48,15 +41,6 @@ func (p *PeersUpdateManager) SendUpdate(ctx context.Context, peerID string, upda
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
var found, dropped bool
|
var found, dropped bool
|
||||||
|
|
||||||
// skip sending sync update to the peer if there is no change in update message,
|
|
||||||
// it will not check on turn credential refresh as we do not send network map or client posture checks
|
|
||||||
if update.NetworkMap != nil {
|
|
||||||
updated := p.handlePeerMessageUpdate(ctx, peerID, update)
|
|
||||||
if !updated {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.channelsMux.Lock()
|
p.channelsMux.Lock()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -66,16 +50,6 @@ func (p *PeersUpdateManager) SendUpdate(ctx context.Context, peerID string, upda
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if update.NetworkMap != nil {
|
|
||||||
lastSentUpdate := p.peerUpdateMessage[peerID]
|
|
||||||
if lastSentUpdate != nil && lastSentUpdate.Update.NetworkMap.GetSerial() > update.Update.NetworkMap.GetSerial() {
|
|
||||||
log.WithContext(ctx).Debugf("peer %s new network map serial: %d not greater than last sent: %d, skip sending update",
|
|
||||||
peerID, update.Update.NetworkMap.GetSerial(), lastSentUpdate.Update.NetworkMap.GetSerial())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.peerUpdateMessage[peerID] = update
|
|
||||||
}
|
|
||||||
|
|
||||||
if channel, ok := p.peerChannels[peerID]; ok {
|
if channel, ok := p.peerChannels[peerID]; ok {
|
||||||
found = true
|
found = true
|
||||||
select {
|
select {
|
||||||
@ -108,7 +82,6 @@ func (p *PeersUpdateManager) CreateChannel(ctx context.Context, peerID string) c
|
|||||||
closed = true
|
closed = true
|
||||||
delete(p.peerChannels, peerID)
|
delete(p.peerChannels, peerID)
|
||||||
close(channel)
|
close(channel)
|
||||||
delete(p.peerUpdateMessage, peerID)
|
|
||||||
}
|
}
|
||||||
// mbragin: todo shouldn't it be more? or configurable?
|
// mbragin: todo shouldn't it be more? or configurable?
|
||||||
channel := make(chan *UpdateMessage, channelBufferSize)
|
channel := make(chan *UpdateMessage, channelBufferSize)
|
||||||
@ -123,7 +96,6 @@ func (p *PeersUpdateManager) closeChannel(ctx context.Context, peerID string) {
|
|||||||
if channel, ok := p.peerChannels[peerID]; ok {
|
if channel, ok := p.peerChannels[peerID]; ok {
|
||||||
delete(p.peerChannels, peerID)
|
delete(p.peerChannels, peerID)
|
||||||
close(channel)
|
close(channel)
|
||||||
delete(p.peerUpdateMessage, peerID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithContext(ctx).Debugf("closed updates channel of a peer %s", peerID)
|
log.WithContext(ctx).Debugf("closed updates channel of a peer %s", peerID)
|
||||||
@ -200,79 +172,3 @@ func (p *PeersUpdateManager) HasChannel(peerID string) bool {
|
|||||||
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlePeerMessageUpdate checks if the update message for a peer is new and should be sent.
|
|
||||||
func (p *PeersUpdateManager) handlePeerMessageUpdate(ctx context.Context, peerID string, update *UpdateMessage) bool {
|
|
||||||
p.channelsMux.RLock()
|
|
||||||
lastSentUpdate := p.peerUpdateMessage[peerID]
|
|
||||||
p.channelsMux.RUnlock()
|
|
||||||
|
|
||||||
if lastSentUpdate != nil {
|
|
||||||
updated, err := isNewPeerUpdateMessage(ctx, lastSentUpdate, update, p.metrics)
|
|
||||||
if err != nil {
|
|
||||||
log.WithContext(ctx).Errorf("error checking for SyncResponse updates: %v", err)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !updated {
|
|
||||||
log.WithContext(ctx).Debugf("peer %s network map is not updated, skip sending update", peerID)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// isNewPeerUpdateMessage checks if the given current update message is a new update that should be sent.
|
|
||||||
func isNewPeerUpdateMessage(ctx context.Context, lastSentUpdate, currUpdateToSend *UpdateMessage, metric telemetry.AppMetrics) (isNew bool, err error) {
|
|
||||||
startTime := time.Now()
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
log.WithContext(ctx).Panicf("comparing peer update messages. Trace: %s", debug.Stack())
|
|
||||||
isNew, err = true, nil
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if lastSentUpdate.Update.NetworkMap.GetSerial() > currUpdateToSend.Update.NetworkMap.GetSerial() {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
differ, err := diff.NewDiffer(
|
|
||||||
diff.CustomValueDiffers(&differs.NetIPAddr{}),
|
|
||||||
diff.CustomValueDiffers(&differs.NetIPPrefix{}),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to create differ: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSentFiles := getChecksFiles(lastSentUpdate.Update.Checks)
|
|
||||||
currFiles := getChecksFiles(currUpdateToSend.Update.Checks)
|
|
||||||
|
|
||||||
changelog, err := differ.Diff(lastSentFiles, currFiles)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to diff checks: %v", err)
|
|
||||||
}
|
|
||||||
if len(changelog) > 0 {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
changelog, err = differ.Diff(lastSentUpdate.NetworkMap, currUpdateToSend.NetworkMap)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to diff network map: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if metric != nil {
|
|
||||||
metric.UpdateChannelMetrics().CountNetworkMapDiffDurationMicro(time.Since(startTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(changelog) > 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getChecksFiles returns a list of files from the given checks.
|
|
||||||
func getChecksFiles(checks []*proto.Checks) []string {
|
|
||||||
files := make([]string, 0, len(checks))
|
|
||||||
for _, check := range checks {
|
|
||||||
files = append(files, check.GetFiles()...)
|
|
||||||
}
|
|
||||||
return files
|
|
||||||
}
|
|
||||||
|
@ -2,21 +2,10 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
|
||||||
"net/netip"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
nbdns "github.com/netbirdio/netbird/dns"
|
|
||||||
"github.com/netbirdio/netbird/management/domain"
|
|
||||||
"github.com/netbirdio/netbird/management/proto"
|
"github.com/netbirdio/netbird/management/proto"
|
||||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
|
||||||
"github.com/netbirdio/netbird/management/server/posture"
|
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
|
||||||
nbroute "github.com/netbirdio/netbird/route"
|
|
||||||
"github.com/netbirdio/netbird/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// var peersUpdater *PeersUpdateManager
|
// var peersUpdater *PeersUpdateManager
|
||||||
@ -88,474 +77,3 @@ func TestCloseChannel(t *testing.T) {
|
|||||||
t.Error("Error closing the channel")
|
t.Error("Error closing the channel")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlePeerMessageUpdate(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
peerID string
|
|
||||||
existingUpdate *UpdateMessage
|
|
||||||
newUpdate *UpdateMessage
|
|
||||||
expectedResult bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "update message with turn credentials update",
|
|
||||||
peerID: "peer",
|
|
||||||
newUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
WiretrusteeConfig: &proto.WiretrusteeConfig{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "update message for peer without existing update",
|
|
||||||
peerID: "peer1",
|
|
||||||
newUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 1},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 2}},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "update message with no changes in update",
|
|
||||||
peerID: "peer2",
|
|
||||||
existingUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 1},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 1}},
|
|
||||||
},
|
|
||||||
newUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 1},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 1}},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "update message with changes in checks",
|
|
||||||
peerID: "peer3",
|
|
||||||
existingUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 1},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 1}},
|
|
||||||
},
|
|
||||||
newUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 2},
|
|
||||||
Checks: []*proto.Checks{
|
|
||||||
{
|
|
||||||
Files: []string{"/usr/bin/netbird"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 2}},
|
|
||||||
},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "update message with lower serial number",
|
|
||||||
peerID: "peer4",
|
|
||||||
existingUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 2},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 2}},
|
|
||||||
},
|
|
||||||
newUpdate: &UpdateMessage{
|
|
||||||
Update: &proto.SyncResponse{
|
|
||||||
NetworkMap: &proto.NetworkMap{Serial: 1},
|
|
||||||
},
|
|
||||||
NetworkMap: &NetworkMap{Network: &Network{Serial: 1}},
|
|
||||||
},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
metrics, err := telemetry.NewDefaultAppMetrics(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
p := NewPeersUpdateManager(metrics)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
if tt.existingUpdate != nil {
|
|
||||||
p.peerUpdateMessage[tt.peerID] = tt.existingUpdate
|
|
||||||
}
|
|
||||||
|
|
||||||
result := p.handlePeerMessageUpdate(ctx, tt.peerID, tt.newUpdate)
|
|
||||||
assert.Equal(t, tt.expectedResult, result)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsNewPeerUpdateMessage(t *testing.T) {
|
|
||||||
t.Run("Unchanged value", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Unchanged value with serial incremented", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating routes network", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.Routes[0].Network = netip.MustParsePrefix("1.1.1.1/32")
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating routes groups", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.Routes[0].Groups = []string{"randomGroup1"}
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating network map peers", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newPeer := &nbpeer.Peer{
|
|
||||||
IP: net.ParseIP("192.168.1.4"),
|
|
||||||
SSHEnabled: true,
|
|
||||||
Key: "peer4-key",
|
|
||||||
DNSLabel: "peer4",
|
|
||||||
SSHKey: "peer4-ssh-key",
|
|
||||||
}
|
|
||||||
newUpdateMessage2.NetworkMap.Peers = append(newUpdateMessage2.NetworkMap.Peers, newPeer)
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating process check", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, message)
|
|
||||||
|
|
||||||
newUpdateMessage3 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage3.Update.Checks = []*proto.Checks{}
|
|
||||||
newUpdateMessage3.Update.NetworkMap.Serial++
|
|
||||||
message, err = isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage3, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
|
|
||||||
newUpdateMessage4 := createMockUpdateMessage(t)
|
|
||||||
check := &posture.Checks{
|
|
||||||
Checks: posture.ChecksDefinition{
|
|
||||||
ProcessCheck: &posture.ProcessCheck{
|
|
||||||
Processes: []posture.Process{
|
|
||||||
{
|
|
||||||
LinuxPath: "/usr/local/netbird",
|
|
||||||
MacPath: "/usr/bin/netbird",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
newUpdateMessage4.Update.Checks = []*proto.Checks{toProtocolCheck(check)}
|
|
||||||
newUpdateMessage4.Update.NetworkMap.Serial++
|
|
||||||
message, err = isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage4, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
|
|
||||||
newUpdateMessage5 := createMockUpdateMessage(t)
|
|
||||||
check = &posture.Checks{
|
|
||||||
Checks: posture.ChecksDefinition{
|
|
||||||
ProcessCheck: &posture.ProcessCheck{
|
|
||||||
Processes: []posture.Process{
|
|
||||||
{
|
|
||||||
LinuxPath: "/usr/bin/netbird",
|
|
||||||
WindowsPath: "C:\\Program Files\\netbird\\netbird.exe",
|
|
||||||
MacPath: "/usr/local/netbird",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
newUpdateMessage5.Update.Checks = []*proto.Checks{toProtocolCheck(check)}
|
|
||||||
newUpdateMessage5.Update.NetworkMap.Serial++
|
|
||||||
message, err = isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage5, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating DNS configuration", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newDomain := "newexample.com"
|
|
||||||
newUpdateMessage2.NetworkMap.DNSConfig.NameServerGroups[0].Domains = append(
|
|
||||||
newUpdateMessage2.NetworkMap.DNSConfig.NameServerGroups[0].Domains,
|
|
||||||
newDomain,
|
|
||||||
)
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating peer IP", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.Peers[0].IP = net.ParseIP("192.168.1.10")
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating firewall rule", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.FirewallRules[0].Port = "443"
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Add new firewall rule", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newRule := &FirewallRule{
|
|
||||||
PeerIP: "192.168.1.3",
|
|
||||||
Direction: firewallRuleDirectionOUT,
|
|
||||||
Action: string(PolicyTrafficActionDrop),
|
|
||||||
Protocol: string(PolicyRuleProtocolUDP),
|
|
||||||
Port: "53",
|
|
||||||
}
|
|
||||||
newUpdateMessage2.NetworkMap.FirewallRules = append(newUpdateMessage2.NetworkMap.FirewallRules, newRule)
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Removing nameserver", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.DNSConfig.NameServerGroups[0].NameServers = make([]nbdns.NameServer, 0)
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating name server IP", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.DNSConfig.NameServerGroups[0].NameServers[0].IP = netip.MustParseAddr("8.8.4.4")
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Updating custom DNS zone", func(t *testing.T) {
|
|
||||||
newUpdateMessage1 := createMockUpdateMessage(t)
|
|
||||||
newUpdateMessage2 := createMockUpdateMessage(t)
|
|
||||||
|
|
||||||
newUpdateMessage2.NetworkMap.DNSConfig.CustomZones[0].Records[0].RData = "100.64.0.2"
|
|
||||||
newUpdateMessage2.Update.NetworkMap.Serial++
|
|
||||||
|
|
||||||
message, err := isNewPeerUpdateMessage(context.Background(), newUpdateMessage1, newUpdateMessage2, nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, message)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func createMockUpdateMessage(t *testing.T) *UpdateMessage {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
_, ipNet, err := net.ParseCIDR("192.168.1.0/24")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
domainList, err := domain.FromStringList([]string{"example.com"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
config := &Config{
|
|
||||||
Signal: &Host{
|
|
||||||
Proto: "https",
|
|
||||||
URI: "signal.uri",
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
},
|
|
||||||
Stuns: []*Host{{URI: "stun.uri", Proto: UDP}},
|
|
||||||
TURNConfig: &TURNConfig{
|
|
||||||
Turns: []*Host{{URI: "turn.uri", Proto: UDP, Username: "turn-user", Password: "turn-pass"}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
peer := &nbpeer.Peer{
|
|
||||||
IP: net.ParseIP("192.168.1.1"),
|
|
||||||
SSHEnabled: true,
|
|
||||||
Key: "peer-key",
|
|
||||||
DNSLabel: "peer1",
|
|
||||||
SSHKey: "peer1-ssh-key",
|
|
||||||
}
|
|
||||||
|
|
||||||
secretManager := NewTimeBasedAuthSecretsManager(
|
|
||||||
NewPeersUpdateManager(nil),
|
|
||||||
&TURNConfig{
|
|
||||||
TimeBasedCredentials: false,
|
|
||||||
CredentialsTTL: util.Duration{
|
|
||||||
Duration: defaultDuration,
|
|
||||||
},
|
|
||||||
Secret: "secret",
|
|
||||||
Turns: []*Host{TurnTestHost},
|
|
||||||
},
|
|
||||||
&Relay{
|
|
||||||
Addresses: []string{"localhost:0"},
|
|
||||||
CredentialsTTL: util.Duration{Duration: time.Hour},
|
|
||||||
Secret: "secret",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
networkMap := &NetworkMap{
|
|
||||||
Network: &Network{Net: *ipNet, Serial: 1000},
|
|
||||||
Peers: []*nbpeer.Peer{{IP: net.ParseIP("192.168.1.2"), Key: "peer2-key", DNSLabel: "peer2", SSHEnabled: true, SSHKey: "peer2-ssh-key"}},
|
|
||||||
OfflinePeers: []*nbpeer.Peer{{IP: net.ParseIP("192.168.1.3"), Key: "peer3-key", DNSLabel: "peer3", SSHEnabled: true, SSHKey: "peer3-ssh-key"}},
|
|
||||||
Routes: []*nbroute.Route{
|
|
||||||
{
|
|
||||||
ID: "route1",
|
|
||||||
Network: netip.MustParsePrefix("10.0.0.0/24"),
|
|
||||||
KeepRoute: true,
|
|
||||||
NetID: "route1",
|
|
||||||
Peer: "peer1",
|
|
||||||
NetworkType: 1,
|
|
||||||
Masquerade: true,
|
|
||||||
Metric: 9999,
|
|
||||||
Enabled: true,
|
|
||||||
Groups: []string{"test1", "test2"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "route2",
|
|
||||||
Domains: domainList,
|
|
||||||
KeepRoute: true,
|
|
||||||
NetID: "route2",
|
|
||||||
Peer: "peer1",
|
|
||||||
NetworkType: 1,
|
|
||||||
Masquerade: true,
|
|
||||||
Metric: 9999,
|
|
||||||
Enabled: true,
|
|
||||||
Groups: []string{"test1", "test2"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DNSConfig: nbdns.Config{
|
|
||||||
ServiceEnable: true,
|
|
||||||
NameServerGroups: []*nbdns.NameServerGroup{
|
|
||||||
{
|
|
||||||
NameServers: []nbdns.NameServer{{
|
|
||||||
IP: netip.MustParseAddr("8.8.8.8"),
|
|
||||||
NSType: nbdns.UDPNameServerType,
|
|
||||||
Port: nbdns.DefaultDNSPort,
|
|
||||||
}},
|
|
||||||
Primary: true,
|
|
||||||
Domains: []string{"example.com"},
|
|
||||||
Enabled: true,
|
|
||||||
SearchDomainsEnabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "ns1",
|
|
||||||
NameServers: []nbdns.NameServer{{
|
|
||||||
IP: netip.MustParseAddr("1.1.1.1"),
|
|
||||||
NSType: nbdns.UDPNameServerType,
|
|
||||||
Port: nbdns.DefaultDNSPort,
|
|
||||||
}},
|
|
||||||
Groups: []string{"group1"},
|
|
||||||
Primary: true,
|
|
||||||
Domains: []string{"example.com"},
|
|
||||||
Enabled: true,
|
|
||||||
SearchDomainsEnabled: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CustomZones: []nbdns.CustomZone{{Domain: "example.com", Records: []nbdns.SimpleRecord{{Name: "example.com", Type: 1, Class: "IN", TTL: 60, RData: "100.64.0.1"}}}},
|
|
||||||
},
|
|
||||||
FirewallRules: []*FirewallRule{
|
|
||||||
{PeerIP: "192.168.1.2", Direction: firewallRuleDirectionIN, Action: string(PolicyTrafficActionAccept), Protocol: string(PolicyRuleProtocolTCP), Port: "80"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dnsName := "example.com"
|
|
||||||
checks := []*posture.Checks{
|
|
||||||
{
|
|
||||||
Checks: posture.ChecksDefinition{
|
|
||||||
ProcessCheck: &posture.ProcessCheck{
|
|
||||||
Processes: []posture.Process{
|
|
||||||
{
|
|
||||||
LinuxPath: "/usr/bin/netbird",
|
|
||||||
WindowsPath: "C:\\Program Files\\netbird\\netbird.exe",
|
|
||||||
MacPath: "/usr/bin/netbird",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dnsCache := &DNSConfigCache{}
|
|
||||||
|
|
||||||
turnToken, err := secretManager.GenerateTurnToken()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
relayToken, err := secretManager.GenerateRelayToken()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &UpdateMessage{
|
|
||||||
Update: toSyncResponse(context.Background(), config, peer, turnToken, relayToken, networkMap, dnsName, checks, dnsCache),
|
|
||||||
NetworkMap: networkMap,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user