2023-01-17 17:34:40 +01:00
package server
import (
2024-07-03 11:33:02 +02:00
"context"
2023-06-28 17:29:02 +02:00
"net/netip"
2023-05-19 11:42:25 +02:00
"testing"
2024-07-30 15:38:32 +02:00
"time"
2023-05-19 11:42:25 +02:00
2024-07-30 15:38:32 +02:00
"github.com/stretchr/testify/assert"
2023-05-19 11:42:25 +02:00
"github.com/stretchr/testify/require"
2023-06-28 17:29:02 +02:00
"github.com/netbirdio/netbird/dns"
2023-01-17 17:34:40 +01:00
"github.com/netbirdio/netbird/management/server/activity"
2024-03-27 18:48:48 +01:00
"github.com/netbirdio/netbird/management/server/group"
2023-11-28 13:45:26 +01:00
nbpeer "github.com/netbirdio/netbird/management/server/peer"
2023-01-17 17:34:40 +01:00
"github.com/netbirdio/netbird/management/server/status"
)
const (
dnsGroup1ID = "group1"
dnsGroup2ID = "group2"
dnsPeer1Key = "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8="
dnsPeer2Key = "/yF0+vCfv+mRR5k0dca0TrGdO/oiNeAI58gToZm5NyI="
dnsAccountID = "testingAcc"
dnsAdminUserID = "testingAdminUser"
dnsRegularUserID = "testingRegularUser"
2023-06-28 17:29:02 +02:00
dnsNSGroup1 = "ns1"
2023-01-17 17:34:40 +01:00
)
func TestGetDNSSettings ( t * testing . T ) {
am , err := createDNSManager ( t )
if err != nil {
t . Error ( "failed to create account manager" )
}
account , err := initTestDNSAccount ( t , am )
if err != nil {
2024-05-16 18:28:37 +02:00
t . Fatal ( "failed to init testing account" )
2023-01-17 17:34:40 +01:00
}
2024-07-03 11:33:02 +02:00
dnsSettings , err := am . GetDNSSettings ( context . Background ( ) , account . Id , dnsAdminUserID )
2023-01-17 17:34:40 +01:00
if err != nil {
t . Fatalf ( "Got an error when trying to retrieve the DNS settings with an admin user, err: %s" , err )
}
if dnsSettings == nil {
t . Fatal ( "DNS settings for new accounts shouldn't return nil" )
}
2023-10-11 23:00:56 +02:00
account . DNSSettings = DNSSettings {
2023-01-17 17:34:40 +01:00
DisabledManagementGroups : [ ] string { group1ID } ,
}
2024-07-03 11:33:02 +02:00
err = am . Store . SaveAccount ( context . Background ( ) , account )
2023-01-17 17:34:40 +01:00
if err != nil {
t . Error ( "failed to save testing account with new DNS settings" )
}
2024-07-03 11:33:02 +02:00
dnsSettings , err = am . GetDNSSettings ( context . Background ( ) , account . Id , dnsAdminUserID )
2023-01-17 17:34:40 +01:00
if err != nil {
t . Errorf ( "Got an error when trying to retrieve the DNS settings with an admin user, err: %s" , err )
}
if len ( dnsSettings . DisabledManagementGroups ) != 1 {
t . Errorf ( "DNS settings should have one disabled mgmt group, groups: %s" , dnsSettings . DisabledManagementGroups )
}
2024-07-03 11:33:02 +02:00
_ , err = am . GetDNSSettings ( context . Background ( ) , account . Id , dnsRegularUserID )
2023-01-17 17:34:40 +01:00
if err == nil {
t . Errorf ( "An error should be returned when getting the DNS settings with a regular user" )
}
s , ok := status . FromError ( err )
if ! ok && s . Type ( ) != status . PermissionDenied {
t . Errorf ( "returned error should be Permission Denied, got err: %s" , err )
}
}
func TestSaveDNSSettings ( t * testing . T ) {
testCases := [ ] struct {
name string
userID string
inputSettings * DNSSettings
shouldFail bool
} {
{
name : "Saving As Admin Should Be OK" ,
userID : dnsAdminUserID ,
inputSettings : & DNSSettings {
DisabledManagementGroups : [ ] string { dnsGroup1ID } ,
} ,
} ,
{
name : "Should Not Update Settings As Regular User" ,
userID : dnsRegularUserID ,
inputSettings : & DNSSettings {
DisabledManagementGroups : [ ] string { dnsGroup1ID } ,
} ,
shouldFail : true ,
} ,
{
name : "Should Not Update Settings If Input is Nil" ,
userID : dnsAdminUserID ,
inputSettings : nil ,
shouldFail : true ,
} ,
{
name : "Should Not Update Settings If Group Is Invalid" ,
userID : dnsAdminUserID ,
inputSettings : & DNSSettings {
DisabledManagementGroups : [ ] string { "non-existing-group" } ,
} ,
shouldFail : true ,
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
am , err := createDNSManager ( t )
if err != nil {
t . Error ( "failed to create account manager" )
}
account , err := initTestDNSAccount ( t , am )
if err != nil {
t . Error ( "failed to init testing account" )
}
2024-07-03 11:33:02 +02:00
err = am . SaveDNSSettings ( context . Background ( ) , account . Id , testCase . userID , testCase . inputSettings )
2023-01-17 17:34:40 +01:00
if err != nil {
if testCase . shouldFail {
return
}
t . Error ( err )
}
2024-07-03 11:33:02 +02:00
updatedAccount , err := am . Store . GetAccount ( context . Background ( ) , account . Id )
2023-01-17 17:34:40 +01:00
if err != nil {
t . Errorf ( "should be able to retrieve updated account, got err: %s" , err )
}
require . ElementsMatchf ( t , testCase . inputSettings . DisabledManagementGroups , updatedAccount . DNSSettings . DisabledManagementGroups ,
"resulting DNS settings should match input" )
} )
}
}
func TestGetNetworkMap_DNSConfigSync ( t * testing . T ) {
am , err := createDNSManager ( t )
if err != nil {
t . Error ( "failed to create account manager" )
}
account , err := initTestDNSAccount ( t , am )
if err != nil {
t . Error ( "failed to init testing account" )
}
2023-02-03 10:33:28 +01:00
peer1 , err := account . FindPeerByPubKey ( dnsPeer1Key )
if err != nil {
t . Error ( "failed to init testing account" )
}
peer2 , err := account . FindPeerByPubKey ( dnsPeer2Key )
if err != nil {
t . Error ( "failed to init testing account" )
}
2024-07-03 11:33:02 +02:00
newAccountDNSConfig , err := am . GetNetworkMap ( context . Background ( ) , peer1 . ID )
2023-01-17 17:34:40 +01:00
require . NoError ( t , err )
require . Len ( t , newAccountDNSConfig . DNSConfig . CustomZones , 1 , "default DNS config should have one custom zone for peers" )
require . True ( t , newAccountDNSConfig . DNSConfig . ServiceEnable , "default DNS config should have local DNS service enabled" )
2023-06-28 17:29:02 +02:00
require . Len ( t , newAccountDNSConfig . DNSConfig . NameServerGroups , 0 , "updated DNS config should have no nameserver groups since peer 1 is NS for the only existing NS group" )
2023-01-17 17:34:40 +01:00
dnsSettings := account . DNSSettings . Copy ( )
dnsSettings . DisabledManagementGroups = append ( dnsSettings . DisabledManagementGroups , dnsGroup1ID )
account . DNSSettings = dnsSettings
2024-07-03 11:33:02 +02:00
err = am . Store . SaveAccount ( context . Background ( ) , account )
2023-01-17 17:34:40 +01:00
require . NoError ( t , err )
2024-07-03 11:33:02 +02:00
updatedAccountDNSConfig , err := am . GetNetworkMap ( context . Background ( ) , peer1 . ID )
2023-01-17 17:34:40 +01:00
require . NoError ( t , err )
require . Len ( t , updatedAccountDNSConfig . DNSConfig . CustomZones , 0 , "updated DNS config should have no custom zone when peer belongs to a disabled group" )
require . False ( t , updatedAccountDNSConfig . DNSConfig . ServiceEnable , "updated DNS config should have local DNS service disabled when peer belongs to a disabled group" )
2024-07-03 11:33:02 +02:00
peer2AccountDNSConfig , err := am . GetNetworkMap ( context . Background ( ) , peer2 . ID )
2023-01-17 17:34:40 +01:00
require . NoError ( t , err )
require . Len ( t , peer2AccountDNSConfig . DNSConfig . CustomZones , 1 , "DNS config should have one custom zone for peers not in the disabled group" )
require . True ( t , peer2AccountDNSConfig . DNSConfig . ServiceEnable , "DNS config should have DNS service enabled for peers not in the disabled group" )
2023-06-28 17:29:02 +02:00
require . Len ( t , peer2AccountDNSConfig . DNSConfig . NameServerGroups , 1 , "updated DNS config should have 1 nameserver groups since peer 2 is part of the group All" )
2023-01-17 17:34:40 +01:00
}
func createDNSManager ( t * testing . T ) ( * DefaultAccountManager , error ) {
2023-11-10 16:33:13 +01:00
t . Helper ( )
2023-01-17 17:34:40 +01:00
store , err := createDNSStore ( t )
if err != nil {
return nil , err
}
eventStore := & activity . InMemoryEventStore { }
2024-07-03 11:33:02 +02:00
return BuildManager ( context . Background ( ) , store , NewPeersUpdateManager ( nil ) , nil , "" , "netbird.test" , eventStore , nil , false , MocIntegratedValidator { } )
2023-01-17 17:34:40 +01:00
}
func createDNSStore ( t * testing . T ) ( Store , error ) {
2023-11-10 16:33:13 +01:00
t . Helper ( )
2023-01-17 17:34:40 +01:00
dataDir := t . TempDir ( )
2024-07-03 11:33:02 +02:00
store , cleanUp , err := NewTestStoreFromJson ( context . Background ( ) , dataDir )
2023-01-17 17:34:40 +01:00
if err != nil {
return nil , err
}
2024-05-16 18:28:37 +02:00
t . Cleanup ( cleanUp )
2023-01-17 17:34:40 +01:00
return store , nil
}
func initTestDNSAccount ( t * testing . T , am * DefaultAccountManager ) ( * Account , error ) {
2023-11-10 16:33:13 +01:00
t . Helper ( )
2023-11-28 13:45:26 +01:00
peer1 := & nbpeer . Peer {
2023-01-17 17:34:40 +01:00
Key : dnsPeer1Key ,
Name : "test-host1@netbird.io" ,
2023-11-28 13:45:26 +01:00
Meta : nbpeer . PeerSystemMeta {
2023-01-17 17:34:40 +01:00
Hostname : "test-host1@netbird.io" ,
GoOS : "linux" ,
Kernel : "Linux" ,
Core : "21.04" ,
Platform : "x86_64" ,
OS : "Ubuntu" ,
WtVersion : "development" ,
UIVersion : "development" ,
} ,
DNSLabel : dnsPeer1Key ,
}
2023-11-28 13:45:26 +01:00
peer2 := & nbpeer . Peer {
2023-01-17 17:34:40 +01:00
Key : dnsPeer2Key ,
Name : "test-host2@netbird.io" ,
2023-11-28 13:45:26 +01:00
Meta : nbpeer . PeerSystemMeta {
2023-01-17 17:34:40 +01:00
Hostname : "test-host2@netbird.io" ,
GoOS : "linux" ,
Kernel : "Linux" ,
Core : "21.04" ,
Platform : "x86_64" ,
OS : "Ubuntu" ,
WtVersion : "development" ,
UIVersion : "development" ,
} ,
DNSLabel : dnsPeer2Key ,
}
domain := "example.com"
2024-07-03 11:33:02 +02:00
account := newAccountWithId ( context . Background ( ) , dnsAccountID , dnsAdminUserID , domain )
2023-01-17 17:34:40 +01:00
account . Users [ dnsRegularUserID ] = & User {
Id : dnsRegularUserID ,
Role : UserRoleUser ,
}
2024-07-03 11:33:02 +02:00
err := am . Store . SaveAccount ( context . Background ( ) , account )
2023-01-17 17:34:40 +01:00
if err != nil {
return nil , err
}
2024-07-03 11:33:02 +02:00
savedPeer1 , _ , _ , err := am . AddPeer ( context . Background ( ) , "" , dnsAdminUserID , peer1 )
2023-02-03 10:33:28 +01:00
if err != nil {
return nil , err
}
2024-07-03 11:33:02 +02:00
_ , _ , _ , err = am . AddPeer ( context . Background ( ) , "" , dnsAdminUserID , peer2 )
2023-02-03 10:33:28 +01:00
if err != nil {
return nil , err
}
2024-07-03 11:33:02 +02:00
account , err = am . Store . GetAccount ( context . Background ( ) , account . Id )
2023-02-03 10:33:28 +01:00
if err != nil {
return nil , err
}
peer1 , err = account . FindPeerByPubKey ( peer1 . Key )
if err != nil {
return nil , err
}
_ , err = account . FindPeerByPubKey ( peer2 . Key )
if err != nil {
return nil , err
}
2024-03-27 18:48:48 +01:00
newGroup1 := & group . Group {
2023-01-17 17:34:40 +01:00
ID : dnsGroup1ID ,
2023-02-03 10:33:28 +01:00
Peers : [ ] string { peer1 . ID } ,
2023-01-17 17:34:40 +01:00
Name : dnsGroup1ID ,
}
2024-03-27 18:48:48 +01:00
newGroup2 := & group . Group {
2023-01-17 17:34:40 +01:00
ID : dnsGroup2ID ,
Name : dnsGroup2ID ,
}
account . Groups [ newGroup1 . ID ] = newGroup1
account . Groups [ newGroup2 . ID ] = newGroup2
2023-06-28 17:29:02 +02:00
allGroup , err := account . GetGroupAll ( )
if err != nil {
return nil , err
}
account . NameServerGroups [ dnsNSGroup1 ] = & dns . NameServerGroup {
ID : dnsNSGroup1 ,
Name : "ns-group-1" ,
NameServers : [ ] dns . NameServer { {
IP : netip . MustParseAddr ( savedPeer1 . IP . String ( ) ) ,
NSType : dns . UDPNameServerType ,
Port : dns . DefaultDNSPort ,
} } ,
Primary : true ,
Enabled : true ,
Groups : [ ] string { allGroup . ID } ,
}
2024-07-03 11:33:02 +02:00
err = am . Store . SaveAccount ( context . Background ( ) , account )
2023-01-17 17:34:40 +01:00
if err != nil {
return nil , err
}
2024-07-03 11:33:02 +02:00
return am . Store . GetAccount ( context . Background ( ) , account . Id )
2023-01-17 17:34:40 +01:00
}
2024-07-30 15:38:32 +02:00
func TestDNSAccountPeerUpdate ( t * testing . T ) {
manager , account , peer1 , peer2 , peer3 := setupNetworkMapTest ( t )
err := manager . SaveGroup ( context . Background ( ) , account . Id , userID , & group . Group {
ID : "group-id" ,
Name : "GroupA" ,
Peers : [ ] string { peer1 . ID , peer2 . ID , peer3 . ID } ,
} )
assert . NoError ( t , err )
updMsg := manager . peersUpdateManager . CreateChannel ( context . Background ( ) , peer1 . ID )
t . Cleanup ( func ( ) {
manager . peersUpdateManager . CloseChannel ( context . Background ( ) , peer1 . ID )
} )
// Saving DNS settings with unused groups should not update account peers and not send peer update
t . Run ( "saving dns setting with unused 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 { "group-id" } ,
} )
assert . NoError ( t , err )
select {
case <- done :
case <- time . After ( 200 * time . Millisecond ) :
t . Error ( "timeout waiting for peerShouldNotReceiveUpdate" )
}
} )
_ , err = manager . CreateNameServerGroup (
context . Background ( ) , account . Id , "ns-group-1" , "ns-group-1" , [ ] dns . NameServer { {
IP : netip . MustParseAddr ( peer1 . IP . String ( ) ) ,
NSType : dns . UDPNameServerType ,
Port : dns . DefaultDNSPort ,
} } ,
[ ] string { "group-id" } ,
true , [ ] string { } , true , userID , false ,
)
assert . NoError ( t , err )
// Saving DNS settings with used groups should update account peers and send peer update
t . Run ( "saving dns setting with used groups" , func ( t * testing . T ) {
done := make ( chan struct { } )
go func ( ) {
peerShouldReceiveUpdate ( t , updMsg )
close ( done )
} ( )
err := manager . SaveDNSSettings ( context . Background ( ) , account . Id , userID , & DNSSettings {
DisabledManagementGroups : [ ] string { "group-id" } ,
} )
assert . NoError ( t , err )
select {
case <- done :
case <- time . After ( 200 * time . Millisecond ) :
t . Error ( "timeout waiting for peerShouldReceiveUpdate" )
}
} )
// Re-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 ( "re-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 { "group-id" } ,
} )
assert . NoError ( t , err )
select {
case <- done :
case <- time . After ( 200 * time . Millisecond ) :
t . Error ( "timeout waiting for peerShouldNotReceiveUpdate" )
}
} )
}