mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-15 11:21:04 +01:00
6c50b0c84b
This PR removes the GetAccount and SaveAccount operations from the AddPeer and instead makes use of gorm.Transaction to add the new peer.
1183 lines
35 KiB
Go
1183 lines
35 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/netip"
|
|
"os"
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rs/xid"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
nbdns "github.com/netbirdio/netbird/dns"
|
|
"github.com/netbirdio/netbird/management/domain"
|
|
"github.com/netbirdio/netbird/management/proto"
|
|
"github.com/netbirdio/netbird/management/server/activity"
|
|
nbgroup "github.com/netbirdio/netbird/management/server/group"
|
|
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"
|
|
)
|
|
|
|
func TestPeer_LoginExpired(t *testing.T) {
|
|
tt := []struct {
|
|
name string
|
|
expirationEnabled bool
|
|
lastLogin time.Time
|
|
expected bool
|
|
accountSettings *Settings
|
|
}{
|
|
{
|
|
name: "Peer Login Expiration Disabled. Peer Login Should Not Expire",
|
|
expirationEnabled: false,
|
|
lastLogin: time.Now().UTC().Add(-25 * time.Hour),
|
|
accountSettings: &Settings{
|
|
PeerLoginExpirationEnabled: true,
|
|
PeerLoginExpiration: time.Hour,
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "Peer Login Should Expire",
|
|
expirationEnabled: true,
|
|
lastLogin: time.Now().UTC().Add(-25 * time.Hour),
|
|
accountSettings: &Settings{
|
|
PeerLoginExpirationEnabled: true,
|
|
PeerLoginExpiration: time.Hour,
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "Peer Login Should Not Expire",
|
|
expirationEnabled: true,
|
|
lastLogin: time.Now().UTC(),
|
|
accountSettings: &Settings{
|
|
PeerLoginExpirationEnabled: true,
|
|
PeerLoginExpiration: time.Hour,
|
|
},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, c := range tt {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
peer := &nbpeer.Peer{
|
|
LoginExpirationEnabled: c.expirationEnabled,
|
|
LastLogin: c.lastLogin,
|
|
UserID: userID,
|
|
}
|
|
|
|
expired, _ := peer.LoginExpired(c.accountSettings.PeerLoginExpiration)
|
|
assert.Equal(t, expired, c.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAccountManager_GetNetworkMap(t *testing.T) {
|
|
manager, err := createManager(t)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
expectedId := "test_account"
|
|
userId := "account_creator"
|
|
account, err := createAccount(manager, expectedId, userId, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
setupKey, err := manager.CreateSetupKey(context.Background(), account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
|
if err != nil {
|
|
t.Fatal("error creating setup key")
|
|
return
|
|
}
|
|
|
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peer1, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey1.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
peerKey2, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
_, _, _, err = manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey2.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
networkMap, err := manager.GetNetworkMap(context.Background(), peer1.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if len(networkMap.Peers) != 1 {
|
|
t.Errorf("expecting Account NetworkMap to have 1 peers, got %v", len(networkMap.Peers))
|
|
return
|
|
}
|
|
|
|
if networkMap.Peers[0].Key != peerKey2.PublicKey().String() {
|
|
t.Errorf(
|
|
"expecting Account NetworkMap to have peer with a key %s, got %s",
|
|
peerKey2.PublicKey().String(),
|
|
networkMap.Peers[0].Key,
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestAccountManager_GetNetworkMapWithPolicy(t *testing.T) {
|
|
// TODO: disable until we start use policy again
|
|
t.Skip()
|
|
manager, err := createManager(t)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
expectedID := "test_account"
|
|
userID := "account_creator"
|
|
account, err := createAccount(manager, expectedID, userID, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var setupKey *SetupKey
|
|
for _, key := range account.SetupKeys {
|
|
if key.Type == SetupKeyReusable {
|
|
setupKey = key
|
|
}
|
|
}
|
|
|
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peer1, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey1.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
peerKey2, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
peer2, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey2.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
policies, err := manager.ListPolicies(context.Background(), account.Id, userID)
|
|
if err != nil {
|
|
t.Errorf("expecting to get a list of rules, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
err = manager.DeletePolicy(context.Background(), account.Id, policies[0].ID, userID)
|
|
if err != nil {
|
|
t.Errorf("expecting to delete 1 group, got failure %v", err)
|
|
return
|
|
}
|
|
var (
|
|
group1 nbgroup.Group
|
|
group2 nbgroup.Group
|
|
policy Policy
|
|
)
|
|
|
|
group1.ID = xid.New().String()
|
|
group2.ID = xid.New().String()
|
|
group1.Name = "src"
|
|
group2.Name = "dst"
|
|
policy.ID = xid.New().String()
|
|
group1.Peers = append(group1.Peers, peer1.ID)
|
|
group2.Peers = append(group2.Peers, peer2.ID)
|
|
|
|
err = manager.SaveGroup(context.Background(), account.Id, userID, &group1)
|
|
if err != nil {
|
|
t.Errorf("expecting group1 to be added, got failure %v", err)
|
|
return
|
|
}
|
|
err = manager.SaveGroup(context.Background(), account.Id, userID, &group2)
|
|
if err != nil {
|
|
t.Errorf("expecting group2 to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
policy.Name = "test"
|
|
policy.Enabled = true
|
|
policy.Rules = []*PolicyRule{
|
|
{
|
|
Enabled: true,
|
|
Sources: []string{group1.ID},
|
|
Destinations: []string{group2.ID},
|
|
Bidirectional: true,
|
|
Action: PolicyTrafficActionAccept,
|
|
},
|
|
}
|
|
err = manager.SavePolicy(context.Background(), account.Id, userID, &policy)
|
|
if err != nil {
|
|
t.Errorf("expecting rule to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
networkMap1, err := manager.GetNetworkMap(context.Background(), peer1.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if len(networkMap1.Peers) != 1 {
|
|
t.Errorf(
|
|
"expecting Account NetworkMap to have 1 peers, got %v: %v",
|
|
len(networkMap1.Peers),
|
|
networkMap1.Peers,
|
|
)
|
|
return
|
|
}
|
|
|
|
if networkMap1.Peers[0].Key != peerKey2.PublicKey().String() {
|
|
t.Errorf(
|
|
"expecting Account NetworkMap to have peer with a key %s, got %s",
|
|
peerKey2.PublicKey().String(),
|
|
networkMap1.Peers[0].Key,
|
|
)
|
|
}
|
|
|
|
networkMap2, err := manager.GetNetworkMap(context.Background(), peer2.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if len(networkMap2.Peers) != 1 {
|
|
t.Errorf("expecting Account NetworkMap to have 1 peers, got %v", len(networkMap2.Peers))
|
|
}
|
|
|
|
if len(networkMap2.Peers) > 0 && networkMap2.Peers[0].Key != peerKey1.PublicKey().String() {
|
|
t.Errorf(
|
|
"expecting Account NetworkMap to have peer with a key %s, got %s",
|
|
peerKey1.PublicKey().String(),
|
|
networkMap2.Peers[0].Key,
|
|
)
|
|
}
|
|
|
|
policy.Enabled = false
|
|
err = manager.SavePolicy(context.Background(), account.Id, userID, &policy)
|
|
if err != nil {
|
|
t.Errorf("expecting rule to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
networkMap1, err = manager.GetNetworkMap(context.Background(), peer1.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if len(networkMap1.Peers) != 0 {
|
|
t.Errorf(
|
|
"expecting Account NetworkMap to have 0 peers, got %v: %v",
|
|
len(networkMap1.Peers),
|
|
networkMap1.Peers,
|
|
)
|
|
return
|
|
}
|
|
|
|
networkMap2, err = manager.GetNetworkMap(context.Background(), peer2.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if len(networkMap2.Peers) != 0 {
|
|
t.Errorf("expecting Account NetworkMap to have 0 peers, got %v", len(networkMap2.Peers))
|
|
}
|
|
}
|
|
|
|
func TestAccountManager_GetPeerNetwork(t *testing.T) {
|
|
manager, err := createManager(t)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
expectedId := "test_account"
|
|
userId := "account_creator"
|
|
account, err := createAccount(manager, expectedId, userId, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
setupKey, err := manager.CreateSetupKey(context.Background(), account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
|
if err != nil {
|
|
t.Fatal("error creating setup key")
|
|
return
|
|
}
|
|
|
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peer1, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey1.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
peerKey2, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
_, _, _, err = manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey2.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
network, err := manager.GetPeerNetwork(context.Background(), peer1.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
if account.Network.Identifier != network.Identifier {
|
|
t.Errorf("expecting Account Networks ID to be equal, got %s expected %s", network.Identifier, account.Network.Identifier)
|
|
}
|
|
}
|
|
|
|
func TestDefaultAccountManager_GetPeer(t *testing.T) {
|
|
manager, err := createManager(t)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// account with an admin and a regular user
|
|
accountID := "test_account"
|
|
adminUser := "account_creator"
|
|
someUser := "some_user"
|
|
account := newAccountWithId(context.Background(), accountID, adminUser, "")
|
|
account.Users[someUser] = &User{
|
|
Id: someUser,
|
|
Role: UserRoleUser,
|
|
}
|
|
account.Settings.RegularUsersViewBlocked = false
|
|
|
|
err = manager.Store.SaveAccount(context.Background(), account)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// two peers one added by a regular user and one with a setup key
|
|
setupKey, err := manager.CreateSetupKey(context.Background(), account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, adminUser, false)
|
|
if err != nil {
|
|
t.Fatal("error creating setup key")
|
|
return
|
|
}
|
|
|
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peer1, _, _, err := manager.AddPeer(context.Background(), "", someUser, &nbpeer.Peer{
|
|
Key: peerKey1.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
peerKey2, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// the second peer added with a setup key
|
|
peer2, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
|
|
Key: peerKey2.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// the user can see its own peer
|
|
peer, err := manager.GetPeer(context.Background(), accountID, peer1.ID, someUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
assert.NotNil(t, peer)
|
|
|
|
// the user can see peer2 because peer1 of the user has access to peer2 due to the All group and the default rule 0 all-to-all access
|
|
peer, err = manager.GetPeer(context.Background(), accountID, peer2.ID, someUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
assert.NotNil(t, peer)
|
|
|
|
// delete the all-to-all policy so that user's peer1 has no access to peer2
|
|
for _, policy := range account.Policies {
|
|
err = manager.DeletePolicy(context.Background(), accountID, policy.ID, adminUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
// at this point the user can't see the details of peer2
|
|
peer, err = manager.GetPeer(context.Background(), accountID, peer2.ID, someUser) //nolint
|
|
assert.Error(t, err)
|
|
|
|
// admin users can always access all the peers
|
|
peer, err = manager.GetPeer(context.Background(), accountID, peer1.ID, adminUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
assert.NotNil(t, peer)
|
|
|
|
peer, err = manager.GetPeer(context.Background(), accountID, peer2.ID, adminUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
assert.NotNil(t, peer)
|
|
}
|
|
|
|
func TestDefaultAccountManager_GetPeers(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
role UserRole
|
|
limitedViewSettings bool
|
|
isServiceUser bool
|
|
expectedPeerCount int
|
|
}{
|
|
{
|
|
name: "Regular user, no limited view settings, not a service user",
|
|
role: UserRoleUser,
|
|
limitedViewSettings: false,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 1,
|
|
},
|
|
{
|
|
name: "Service user, no limited view settings",
|
|
role: UserRoleUser,
|
|
limitedViewSettings: false,
|
|
isServiceUser: true,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Regular user, limited view settings",
|
|
role: UserRoleUser,
|
|
limitedViewSettings: true,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 0,
|
|
},
|
|
{
|
|
name: "Service user, limited view settings",
|
|
role: UserRoleUser,
|
|
limitedViewSettings: true,
|
|
isServiceUser: true,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Admin, no limited view settings, not a service user",
|
|
role: UserRoleAdmin,
|
|
limitedViewSettings: false,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Admin service user, no limited view settings",
|
|
role: UserRoleAdmin,
|
|
limitedViewSettings: false,
|
|
isServiceUser: true,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Admin, limited view settings",
|
|
role: UserRoleAdmin,
|
|
limitedViewSettings: true,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Admin Service user, limited view settings",
|
|
role: UserRoleAdmin,
|
|
limitedViewSettings: true,
|
|
isServiceUser: true,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Owner, no limited view settings",
|
|
role: UserRoleOwner,
|
|
limitedViewSettings: true,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 2,
|
|
},
|
|
{
|
|
name: "Owner, limited view settings",
|
|
role: UserRoleOwner,
|
|
limitedViewSettings: true,
|
|
isServiceUser: false,
|
|
expectedPeerCount: 2,
|
|
},
|
|
}
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
manager, err := createManager(t)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// account with an admin and a regular user
|
|
accountID := "test_account"
|
|
adminUser := "account_creator"
|
|
someUser := "some_user"
|
|
account := newAccountWithId(context.Background(), accountID, adminUser, "")
|
|
account.Users[someUser] = &User{
|
|
Id: someUser,
|
|
Role: testCase.role,
|
|
IsServiceUser: testCase.isServiceUser,
|
|
}
|
|
account.Policies = []*Policy{}
|
|
account.Settings.RegularUsersViewBlocked = testCase.limitedViewSettings
|
|
|
|
err = manager.Store.SaveAccount(context.Background(), account)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
peerKey2, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
|
|
_, _, _, err = manager.AddPeer(context.Background(), "", someUser, &nbpeer.Peer{
|
|
Key: peerKey1.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
_, _, _, err = manager.AddPeer(context.Background(), "", adminUser, &nbpeer.Peer{
|
|
Key: peerKey2.PublicKey().String(),
|
|
Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("expecting peer to be added, got failure %v", err)
|
|
return
|
|
}
|
|
|
|
peers, err := manager.GetPeers(context.Background(), accountID, someUser)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
return
|
|
}
|
|
assert.NotNil(t, peers)
|
|
|
|
assert.Len(t, peers, testCase.expectedPeerCount)
|
|
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func setupTestAccountManager(b *testing.B, peers int, groups int) (*DefaultAccountManager, string, string, error) {
|
|
b.Helper()
|
|
|
|
manager, err := createManager(b)
|
|
if err != nil {
|
|
return nil, "", "", err
|
|
}
|
|
|
|
accountID := "test_account"
|
|
adminUser := "account_creator"
|
|
regularUser := "regular_user"
|
|
|
|
account := newAccountWithId(context.Background(), accountID, adminUser, "")
|
|
account.Users[regularUser] = &User{
|
|
Id: regularUser,
|
|
Role: UserRoleUser,
|
|
}
|
|
|
|
// Create peers
|
|
for i := 0; i < peers; i++ {
|
|
peerKey, _ := wgtypes.GeneratePrivateKey()
|
|
peer := &nbpeer.Peer{
|
|
ID: fmt.Sprintf("peer-%d", i),
|
|
DNSLabel: fmt.Sprintf("peer-%d", i),
|
|
Key: peerKey.PublicKey().String(),
|
|
IP: net.ParseIP(fmt.Sprintf("100.64.%d.%d", i/256, i%256)),
|
|
Status: &nbpeer.PeerStatus{},
|
|
UserID: regularUser,
|
|
}
|
|
account.Peers[peer.ID] = peer
|
|
}
|
|
|
|
// Create groups and policies
|
|
account.Policies = make([]*Policy, 0, groups)
|
|
for i := 0; i < groups; i++ {
|
|
groupID := fmt.Sprintf("group-%d", i)
|
|
group := &nbgroup.Group{
|
|
ID: groupID,
|
|
Name: fmt.Sprintf("Group %d", i),
|
|
}
|
|
for j := 0; j < peers/groups; j++ {
|
|
peerIndex := i*(peers/groups) + j
|
|
group.Peers = append(group.Peers, fmt.Sprintf("peer-%d", peerIndex))
|
|
}
|
|
account.Groups[groupID] = group
|
|
|
|
// Create a policy for this group
|
|
policy := &Policy{
|
|
ID: fmt.Sprintf("policy-%d", i),
|
|
Name: fmt.Sprintf("Policy for Group %d", i),
|
|
Enabled: true,
|
|
Rules: []*PolicyRule{
|
|
{
|
|
ID: fmt.Sprintf("rule-%d", i),
|
|
Name: fmt.Sprintf("Rule for Group %d", i),
|
|
Enabled: true,
|
|
Sources: []string{groupID},
|
|
Destinations: []string{groupID},
|
|
Bidirectional: true,
|
|
Protocol: PolicyRuleProtocolALL,
|
|
Action: PolicyTrafficActionAccept,
|
|
},
|
|
},
|
|
}
|
|
account.Policies = append(account.Policies, policy)
|
|
}
|
|
|
|
account.PostureChecks = []*posture.Checks{
|
|
{
|
|
ID: "PostureChecksAll",
|
|
Name: "All",
|
|
Checks: posture.ChecksDefinition{
|
|
NBVersionCheck: &posture.NBVersionCheck{
|
|
MinVersion: "0.0.1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err = manager.Store.SaveAccount(context.Background(), account)
|
|
if err != nil {
|
|
return nil, "", "", err
|
|
}
|
|
|
|
return manager, accountID, regularUser, nil
|
|
}
|
|
|
|
func BenchmarkGetPeers(b *testing.B) {
|
|
benchCases := []struct {
|
|
name string
|
|
peers int
|
|
groups int
|
|
}{
|
|
{"Small", 50, 5},
|
|
{"Medium", 500, 10},
|
|
{"Large", 5000, 20},
|
|
{"Small single", 50, 1},
|
|
{"Medium single", 500, 1},
|
|
{"Large 5", 5000, 5},
|
|
}
|
|
|
|
log.SetOutput(io.Discard)
|
|
defer log.SetOutput(os.Stderr)
|
|
for _, bc := range benchCases {
|
|
b.Run(bc.name, func(b *testing.B) {
|
|
manager, accountID, userID, err := setupTestAccountManager(b, bc.peers, bc.groups)
|
|
if err != nil {
|
|
b.Fatalf("Failed to setup test account manager: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := manager.GetPeers(context.Background(), accountID, userID)
|
|
if err != nil {
|
|
b.Fatalf("GetPeers failed: %v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkUpdateAccountPeers(b *testing.B) {
|
|
benchCases := []struct {
|
|
name string
|
|
peers int
|
|
groups int
|
|
}{
|
|
{"Small", 50, 5},
|
|
{"Medium", 500, 10},
|
|
{"Large", 5000, 20},
|
|
{"Small single", 50, 1},
|
|
{"Medium single", 500, 1},
|
|
{"Large 5", 5000, 5},
|
|
}
|
|
|
|
log.SetOutput(io.Discard)
|
|
defer log.SetOutput(os.Stderr)
|
|
|
|
for _, bc := range benchCases {
|
|
b.Run(bc.name, func(b *testing.B) {
|
|
manager, accountID, _, err := setupTestAccountManager(b, bc.peers, bc.groups)
|
|
if err != nil {
|
|
b.Fatalf("Failed to setup test account manager: %v", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
account, err := manager.Store.GetAccount(ctx, accountID)
|
|
if err != nil {
|
|
b.Fatalf("Failed to get account: %v", err)
|
|
}
|
|
|
|
peerChannels := make(map[string]chan *UpdateMessage)
|
|
|
|
for peerID := range account.Peers {
|
|
peerChannels[peerID] = make(chan *UpdateMessage, channelBufferSize)
|
|
}
|
|
|
|
manager.peersUpdateManager.peerChannels = peerChannels
|
|
|
|
b.ResetTimer()
|
|
start := time.Now()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
manager.updateAccountPeers(ctx, account)
|
|
}
|
|
|
|
duration := time.Since(start)
|
|
b.ReportMetric(float64(duration.Nanoseconds())/float64(b.N)/1e6, "ms/op")
|
|
b.ReportMetric(0, "ns/op")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToSyncResponse(t *testing.T) {
|
|
_, 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",
|
|
}
|
|
turnRelayToken := &Token{
|
|
Payload: "turn-user",
|
|
Signature: "turn-pass",
|
|
}
|
|
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"),
|
|
Domains: domainList,
|
|
KeepRoute: true,
|
|
NetID: "route1",
|
|
Peer: "peer1",
|
|
NetworkType: 1,
|
|
Masquerade: true,
|
|
Metric: 9999,
|
|
Enabled: true,
|
|
},
|
|
},
|
|
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"}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
dnsCache := &DNSConfigCache{}
|
|
|
|
response := toSyncResponse(context.Background(), config, peer, turnRelayToken, turnRelayToken, networkMap, dnsName, checks, dnsCache)
|
|
|
|
assert.NotNil(t, response)
|
|
// assert peer config
|
|
assert.Equal(t, "192.168.1.1/24", response.PeerConfig.Address)
|
|
assert.Equal(t, "peer1.example.com", response.PeerConfig.Fqdn)
|
|
assert.Equal(t, true, response.PeerConfig.SshConfig.SshEnabled)
|
|
// assert wiretrustee config
|
|
assert.Equal(t, "signal.uri", response.WiretrusteeConfig.Signal.Uri)
|
|
assert.Equal(t, proto.HostConfig_HTTPS, response.WiretrusteeConfig.Signal.GetProtocol())
|
|
assert.Equal(t, "stun.uri", response.WiretrusteeConfig.Stuns[0].Uri)
|
|
assert.Equal(t, "turn.uri", response.WiretrusteeConfig.Turns[0].HostConfig.GetUri())
|
|
assert.Equal(t, "turn-user", response.WiretrusteeConfig.Turns[0].User)
|
|
assert.Equal(t, "turn-pass", response.WiretrusteeConfig.Turns[0].Password)
|
|
// assert RemotePeers
|
|
assert.Equal(t, 1, len(response.RemotePeers))
|
|
assert.Equal(t, "192.168.1.2/32", response.RemotePeers[0].AllowedIps[0])
|
|
assert.Equal(t, "peer2-key", response.RemotePeers[0].WgPubKey)
|
|
assert.Equal(t, "peer2.example.com", response.RemotePeers[0].GetFqdn())
|
|
assert.Equal(t, false, response.RemotePeers[0].GetSshConfig().GetSshEnabled())
|
|
assert.Equal(t, []byte("peer2-ssh-key"), response.RemotePeers[0].GetSshConfig().GetSshPubKey())
|
|
// assert network map
|
|
assert.Equal(t, uint64(1000), response.NetworkMap.Serial)
|
|
assert.Equal(t, "192.168.1.1/24", response.NetworkMap.PeerConfig.Address)
|
|
assert.Equal(t, "peer1.example.com", response.NetworkMap.PeerConfig.Fqdn)
|
|
assert.Equal(t, true, response.NetworkMap.PeerConfig.SshConfig.SshEnabled)
|
|
// assert network map RemotePeers
|
|
assert.Equal(t, 1, len(response.NetworkMap.RemotePeers))
|
|
assert.Equal(t, "192.168.1.2/32", response.NetworkMap.RemotePeers[0].AllowedIps[0])
|
|
assert.Equal(t, "peer2-key", response.NetworkMap.RemotePeers[0].WgPubKey)
|
|
assert.Equal(t, "peer2.example.com", response.NetworkMap.RemotePeers[0].GetFqdn())
|
|
assert.Equal(t, []byte("peer2-ssh-key"), response.NetworkMap.RemotePeers[0].GetSshConfig().GetSshPubKey())
|
|
// assert network map OfflinePeers
|
|
assert.Equal(t, 1, len(response.NetworkMap.OfflinePeers))
|
|
assert.Equal(t, "192.168.1.3/32", response.NetworkMap.OfflinePeers[0].AllowedIps[0])
|
|
assert.Equal(t, "peer3-key", response.NetworkMap.OfflinePeers[0].WgPubKey)
|
|
assert.Equal(t, "peer3.example.com", response.NetworkMap.OfflinePeers[0].GetFqdn())
|
|
assert.Equal(t, []byte("peer3-ssh-key"), response.NetworkMap.OfflinePeers[0].GetSshConfig().GetSshPubKey())
|
|
// assert network map Routes
|
|
assert.Equal(t, 1, len(response.NetworkMap.Routes))
|
|
assert.Equal(t, "10.0.0.0/24", response.NetworkMap.Routes[0].Network)
|
|
assert.Equal(t, "route1", response.NetworkMap.Routes[0].ID)
|
|
assert.Equal(t, "peer1", response.NetworkMap.Routes[0].Peer)
|
|
assert.Equal(t, "example.com", response.NetworkMap.Routes[0].Domains[0])
|
|
assert.Equal(t, true, response.NetworkMap.Routes[0].KeepRoute)
|
|
assert.Equal(t, true, response.NetworkMap.Routes[0].Masquerade)
|
|
assert.Equal(t, int64(9999), response.NetworkMap.Routes[0].Metric)
|
|
assert.Equal(t, int64(1), response.NetworkMap.Routes[0].NetworkType)
|
|
assert.Equal(t, "route1", response.NetworkMap.Routes[0].NetID)
|
|
// assert network map DNSConfig
|
|
assert.Equal(t, true, response.NetworkMap.DNSConfig.ServiceEnable)
|
|
assert.Equal(t, 1, len(response.NetworkMap.DNSConfig.CustomZones))
|
|
assert.Equal(t, 2, len(response.NetworkMap.DNSConfig.NameServerGroups))
|
|
// assert network map DNSConfig.CustomZones
|
|
assert.Equal(t, "example.com", response.NetworkMap.DNSConfig.CustomZones[0].Domain)
|
|
assert.Equal(t, 1, len(response.NetworkMap.DNSConfig.CustomZones[0].Records))
|
|
assert.Equal(t, "example.com", response.NetworkMap.DNSConfig.CustomZones[0].Records[0].Name)
|
|
assert.Equal(t, int64(1), response.NetworkMap.DNSConfig.CustomZones[0].Records[0].Type)
|
|
assert.Equal(t, "IN", response.NetworkMap.DNSConfig.CustomZones[0].Records[0].Class)
|
|
assert.Equal(t, int64(60), response.NetworkMap.DNSConfig.CustomZones[0].Records[0].TTL)
|
|
assert.Equal(t, "100.64.0.1", response.NetworkMap.DNSConfig.CustomZones[0].Records[0].RData)
|
|
// assert network map DNSConfig.NameServerGroups
|
|
assert.Equal(t, true, response.NetworkMap.DNSConfig.NameServerGroups[0].Primary)
|
|
assert.Equal(t, true, response.NetworkMap.DNSConfig.NameServerGroups[0].SearchDomainsEnabled)
|
|
assert.Equal(t, "example.com", response.NetworkMap.DNSConfig.NameServerGroups[0].Domains[0])
|
|
assert.Equal(t, "8.8.8.8", response.NetworkMap.DNSConfig.NameServerGroups[0].NameServers[0].GetIP())
|
|
assert.Equal(t, int64(1), response.NetworkMap.DNSConfig.NameServerGroups[0].NameServers[0].GetNSType())
|
|
assert.Equal(t, int64(53), response.NetworkMap.DNSConfig.NameServerGroups[0].NameServers[0].GetPort())
|
|
// assert network map Firewall
|
|
assert.Equal(t, 1, len(response.NetworkMap.FirewallRules))
|
|
assert.Equal(t, "192.168.1.2", response.NetworkMap.FirewallRules[0].PeerIP)
|
|
assert.Equal(t, proto.FirewallRule_IN, response.NetworkMap.FirewallRules[0].Direction)
|
|
assert.Equal(t, proto.FirewallRule_ACCEPT, response.NetworkMap.FirewallRules[0].Action)
|
|
assert.Equal(t, proto.FirewallRule_TCP, response.NetworkMap.FirewallRules[0].Protocol)
|
|
assert.Equal(t, "80", response.NetworkMap.FirewallRules[0].Port)
|
|
// assert posture checks
|
|
assert.Equal(t, 1, len(response.Checks))
|
|
assert.Equal(t, "/usr/bin/netbird", response.Checks[0].Files[0])
|
|
}
|
|
|
|
func Test_RegisterPeerByUser(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("The SQLite store is not properly supported by Windows yet")
|
|
}
|
|
|
|
store := newSqliteStoreFromFile(t, "testdata/extended-store.json")
|
|
|
|
eventStore := &activity.InMemoryEventStore{}
|
|
|
|
metrics, err := telemetry.NewDefaultAppMetrics(context.Background())
|
|
assert.NoError(t, err)
|
|
|
|
am, err := BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics)
|
|
assert.NoError(t, err)
|
|
|
|
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
|
existingUserID := "edafee4e-63fb-11ec-90d6-0242ac120003"
|
|
|
|
_, err = store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
|
|
newPeer := &nbpeer.Peer{
|
|
ID: xid.New().String(),
|
|
AccountID: existingAccountID,
|
|
Key: "newPeerKey",
|
|
SetupKey: "",
|
|
IP: net.IP{123, 123, 123, 123},
|
|
Meta: nbpeer.PeerSystemMeta{
|
|
Hostname: "newPeer",
|
|
GoOS: "linux",
|
|
},
|
|
Name: "newPeerName",
|
|
DNSLabel: "newPeer.test",
|
|
UserID: existingUserID,
|
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
|
SSHEnabled: false,
|
|
LastLogin: time.Now(),
|
|
}
|
|
|
|
addedPeer, _, _, err := am.AddPeer(context.Background(), "", existingUserID, newPeer)
|
|
require.NoError(t, err)
|
|
|
|
peer, err := store.GetPeerByPeerPubKey(context.Background(), LockingStrengthShare, addedPeer.Key)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, peer.AccountID, existingAccountID)
|
|
assert.Equal(t, peer.UserID, existingUserID)
|
|
|
|
account, err := store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, account.Peers, addedPeer.ID)
|
|
assert.Equal(t, peer.Meta.Hostname, newPeer.Meta.Hostname)
|
|
assert.Contains(t, account.Groups["cfefqs706sqkneg59g3g"].Peers, addedPeer.ID)
|
|
assert.Contains(t, account.Groups["cfefqs706sqkneg59g4g"].Peers, addedPeer.ID)
|
|
|
|
assert.Equal(t, uint64(1), account.Network.Serial)
|
|
|
|
lastLogin, err := time.Parse("2006-01-02T15:04:05Z", "0001-01-01T00:00:00Z")
|
|
assert.NoError(t, err)
|
|
assert.NotEqual(t, lastLogin, account.Users[existingUserID].LastLogin)
|
|
}
|
|
|
|
func Test_RegisterPeerBySetupKey(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("The SQLite store is not properly supported by Windows yet")
|
|
}
|
|
|
|
store := newSqliteStoreFromFile(t, "testdata/extended-store.json")
|
|
|
|
eventStore := &activity.InMemoryEventStore{}
|
|
|
|
metrics, err := telemetry.NewDefaultAppMetrics(context.Background())
|
|
assert.NoError(t, err)
|
|
|
|
am, err := BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics)
|
|
assert.NoError(t, err)
|
|
|
|
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
|
existingSetupKeyID := "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"
|
|
|
|
_, err = store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
|
|
newPeer := &nbpeer.Peer{
|
|
ID: xid.New().String(),
|
|
AccountID: existingAccountID,
|
|
Key: "newPeerKey",
|
|
SetupKey: "existingSetupKey",
|
|
UserID: "",
|
|
IP: net.IP{123, 123, 123, 123},
|
|
Meta: nbpeer.PeerSystemMeta{
|
|
Hostname: "newPeer",
|
|
GoOS: "linux",
|
|
},
|
|
Name: "newPeerName",
|
|
DNSLabel: "newPeer.test",
|
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
|
SSHEnabled: false,
|
|
}
|
|
|
|
addedPeer, _, _, err := am.AddPeer(context.Background(), existingSetupKeyID, "", newPeer)
|
|
|
|
require.NoError(t, err)
|
|
|
|
peer, err := store.GetPeerByPeerPubKey(context.Background(), LockingStrengthShare, newPeer.Key)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, peer.AccountID, existingAccountID)
|
|
assert.Equal(t, peer.SetupKey, existingSetupKeyID)
|
|
|
|
account, err := store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, account.Peers, addedPeer.ID)
|
|
assert.Contains(t, account.Groups["cfefqs706sqkneg59g2g"].Peers, addedPeer.ID)
|
|
assert.Contains(t, account.Groups["cfefqs706sqkneg59g4g"].Peers, addedPeer.ID)
|
|
|
|
assert.Equal(t, uint64(1), account.Network.Serial)
|
|
|
|
lastUsed, err := time.Parse("2006-01-02T15:04:05Z", "0001-01-01T00:00:00Z")
|
|
assert.NoError(t, err)
|
|
assert.NotEqual(t, lastUsed, account.SetupKeys[existingSetupKeyID].LastUsed)
|
|
assert.Equal(t, 1, account.SetupKeys[existingSetupKeyID].UsedTimes)
|
|
|
|
}
|
|
|
|
func Test_RegisterPeerRollbackOnFailure(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("The SQLite store is not properly supported by Windows yet")
|
|
}
|
|
|
|
store := newSqliteStoreFromFile(t, "testdata/extended-store.json")
|
|
|
|
eventStore := &activity.InMemoryEventStore{}
|
|
|
|
metrics, err := telemetry.NewDefaultAppMetrics(context.Background())
|
|
assert.NoError(t, err)
|
|
|
|
am, err := BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics)
|
|
assert.NoError(t, err)
|
|
|
|
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
|
faultyKey := "A2C8E62B-38F5-4553-B31E-DD66C696CEBC"
|
|
|
|
_, err = store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
|
|
newPeer := &nbpeer.Peer{
|
|
ID: xid.New().String(),
|
|
AccountID: existingAccountID,
|
|
Key: "newPeerKey",
|
|
SetupKey: "existingSetupKey",
|
|
UserID: "",
|
|
IP: net.IP{123, 123, 123, 123},
|
|
Meta: nbpeer.PeerSystemMeta{
|
|
Hostname: "newPeer",
|
|
GoOS: "linux",
|
|
},
|
|
Name: "newPeerName",
|
|
DNSLabel: "newPeer.test",
|
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
|
SSHEnabled: false,
|
|
}
|
|
|
|
_, _, _, err = am.AddPeer(context.Background(), faultyKey, "", newPeer)
|
|
require.Error(t, err)
|
|
|
|
_, err = store.GetPeerByPeerPubKey(context.Background(), LockingStrengthShare, newPeer.Key)
|
|
require.Error(t, err)
|
|
|
|
account, err := store.GetAccount(context.Background(), existingAccountID)
|
|
require.NoError(t, err)
|
|
assert.NotContains(t, account.Peers, newPeer.ID)
|
|
assert.NotContains(t, account.Groups["cfefqs706sqkneg59g3g"].Peers, newPeer.ID)
|
|
assert.NotContains(t, account.Groups["cfefqs706sqkneg59g4g"].Peers, newPeer.ID)
|
|
|
|
assert.Equal(t, uint64(0), account.Network.Serial)
|
|
|
|
lastUsed, err := time.Parse("2006-01-02T15:04:05Z", "0001-01-01T00:00:00Z")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, lastUsed, account.SetupKeys[faultyKey].LastUsed)
|
|
assert.Equal(t, 0, account.SetupKeys[faultyKey].UsedTimes)
|
|
}
|