extract peer into seperate package

This commit is contained in:
Pascal Fischer 2023-11-28 13:45:26 +01:00
parent a7e55cc5e3
commit a729c83b06
24 changed files with 587 additions and 399 deletions

2
go.mod
View File

@ -51,7 +51,7 @@ require (
github.com/miekg/dns v1.1.43 github.com/miekg/dns v1.1.43
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/nadoo/ipset v0.5.0 github.com/nadoo/ipset v0.5.0
github.com/netbirdio/management-integrations/integrations v0.0.0-20231128103220-a3b41e63c818 github.com/netbirdio/management-integrations/integrations v0.0.0-20231128110844-6dc8ff1bf262
github.com/okta/okta-sdk-golang/v2 v2.18.0 github.com/okta/okta-sdk-golang/v2 v2.18.0
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pion/logging v0.2.2 github.com/pion/logging v0.2.2

2
go.sum
View File

@ -507,6 +507,8 @@ github.com/netbirdio/management-integrations/integrations v0.0.0-20231127171411-
github.com/netbirdio/management-integrations/integrations v0.0.0-20231127171411-ffb4ff80f85a/go.mod h1:aRyvEvLzMX9+eDgW+cMRh0CkxR8sYIszmEITaWFZ5Vc= github.com/netbirdio/management-integrations/integrations v0.0.0-20231127171411-ffb4ff80f85a/go.mod h1:aRyvEvLzMX9+eDgW+cMRh0CkxR8sYIszmEITaWFZ5Vc=
github.com/netbirdio/management-integrations/integrations v0.0.0-20231128103220-a3b41e63c818 h1:PTQ2SSijkoN8Qkctq9oLzEdzCLLv7WoD2dqScmpb15o= github.com/netbirdio/management-integrations/integrations v0.0.0-20231128103220-a3b41e63c818 h1:PTQ2SSijkoN8Qkctq9oLzEdzCLLv7WoD2dqScmpb15o=
github.com/netbirdio/management-integrations/integrations v0.0.0-20231128103220-a3b41e63c818/go.mod h1:aRyvEvLzMX9+eDgW+cMRh0CkxR8sYIszmEITaWFZ5Vc= github.com/netbirdio/management-integrations/integrations v0.0.0-20231128103220-a3b41e63c818/go.mod h1:aRyvEvLzMX9+eDgW+cMRh0CkxR8sYIszmEITaWFZ5Vc=
github.com/netbirdio/management-integrations/integrations v0.0.0-20231128110844-6dc8ff1bf262 h1:JVImKBfZC2tC88GcJS0Hi6sdFL+FkhCcmbpU8lRAWss=
github.com/netbirdio/management-integrations/integrations v0.0.0-20231128110844-6dc8ff1bf262/go.mod h1:aRyvEvLzMX9+eDgW+cMRh0CkxR8sYIszmEITaWFZ5Vc=
github.com/netbirdio/service v0.0.0-20230215170314-b923b89432b0 h1:hirFRfx3grVA/9eEyjME5/z3nxdJlN9kfQpvWWPk32g= github.com/netbirdio/service v0.0.0-20230215170314-b923b89432b0 h1:hirFRfx3grVA/9eEyjME5/z3nxdJlN9kfQpvWWPk32g=
github.com/netbirdio/service v0.0.0-20230215170314-b923b89432b0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= github.com/netbirdio/service v0.0.0-20230215170314-b923b89432b0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/netbirdio/systray v0.0.0-20231030152038-ef1ed2a27949 h1:xbWM9BU6mwZZLHxEjxIX/V8Hv3HurQt4mReIE4mY4DM= github.com/netbirdio/systray v0.0.0-20231030152038-ef1ed2a27949 h1:xbWM9BU6mwZZLHxEjxIX/V8Hv3HurQt4mReIE4mY4DM=

View File

@ -27,6 +27,7 @@ import (
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/idp" "github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/route" "github.com/netbirdio/netbird/route"
) )
@ -68,13 +69,13 @@ type AccountManager interface {
MarkPATUsed(tokenID string) error MarkPATUsed(tokenID string) error
GetUser(claims jwtclaims.AuthorizationClaims) (*User, error) GetUser(claims jwtclaims.AuthorizationClaims) (*User, error)
ListUsers(accountID string) ([]*User, error) ListUsers(accountID string) ([]*User, error)
GetPeers(accountID, userID string) ([]*Peer, error) GetPeers(accountID, userID string) ([]*nbpeer.Peer, error)
MarkPeerConnected(peerKey string, connected bool) error MarkPeerConnected(peerKey string, connected bool) error
DeletePeer(accountID, peerID, userID string) error DeletePeer(accountID, peerID, userID string) error
UpdatePeer(accountID, userID string, peer *Peer) (*Peer, error) UpdatePeer(accountID, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, error)
GetNetworkMap(peerID string) (*NetworkMap, error) GetNetworkMap(peerID string) (*NetworkMap, error)
GetPeerNetwork(peerID string) (*Network, error) GetPeerNetwork(peerID string) (*Network, error)
AddPeer(setupKey, userID string, peer *Peer) (*Peer, *NetworkMap, error) AddPeer(setupKey, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, *NetworkMap, error)
CreatePAT(accountID string, initiatorUserID string, targetUserID string, tokenName string, expiresIn int) (*PersonalAccessTokenGenerated, error) CreatePAT(accountID string, initiatorUserID string, targetUserID string, tokenName string, expiresIn int) (*PersonalAccessTokenGenerated, error)
DeletePAT(accountID string, initiatorUserID string, targetUserID string, tokenID string) error DeletePAT(accountID string, initiatorUserID string, targetUserID string, tokenID string) error
GetPAT(accountID string, initiatorUserID string, targetUserID string, tokenID string) (*PersonalAccessToken, error) GetPAT(accountID string, initiatorUserID string, targetUserID string, tokenID string) (*PersonalAccessToken, error)
@ -106,10 +107,10 @@ type AccountManager interface {
GetEvents(accountID, userID string) ([]*activity.Event, error) GetEvents(accountID, userID string) ([]*activity.Event, error)
GetDNSSettings(accountID string, userID string) (*DNSSettings, error) GetDNSSettings(accountID string, userID string) (*DNSSettings, error)
SaveDNSSettings(accountID string, userID string, dnsSettingsToSave *DNSSettings) error SaveDNSSettings(accountID string, userID string, dnsSettingsToSave *DNSSettings) error
GetPeer(accountID, peerID, userID string) (*Peer, error) GetPeer(accountID, peerID, userID string) (*nbpeer.Peer, error)
UpdateAccountSettings(accountID, userID string, newSettings *Settings) (*Account, error) UpdateAccountSettings(accountID, userID string, newSettings *Settings) (*Account, error)
LoginPeer(login PeerLogin) (*Peer, *NetworkMap, error) // used by peer gRPC API LoginPeer(login PeerLogin) (*nbpeer.Peer, *NetworkMap, error) // used by peer gRPC API
SyncPeer(sync PeerSync) (*Peer, *NetworkMap, error) // used by peer gRPC API SyncPeer(sync PeerSync) (*nbpeer.Peer, *NetworkMap, error) // used by peer gRPC API
GetAllConnectedPeers() (map[string]struct{}, error) GetAllConnectedPeers() (map[string]struct{}, error)
GetExternalCacheManager() ExternalCacheManager GetExternalCacheManager() ExternalCacheManager
} }
@ -164,20 +165,31 @@ type Settings struct {
Extra *ExtraSettings Extra *ExtraSettings
} }
type ExtraSettings struct {
// PeerApprovalEnabled enables or disables the need for peers bo be approved by an administrator
PeerApprovalEnabled bool
}
// Copy copies the Settings struct // Copy copies the Settings struct
func (s *Settings) Copy() *Settings { func (s *Settings) Copy() *Settings {
return &Settings{ settings := &Settings{
PeerLoginExpirationEnabled: s.PeerLoginExpirationEnabled, PeerLoginExpirationEnabled: s.PeerLoginExpirationEnabled,
PeerLoginExpiration: s.PeerLoginExpiration, PeerLoginExpiration: s.PeerLoginExpiration,
JWTGroupsEnabled: s.JWTGroupsEnabled, JWTGroupsEnabled: s.JWTGroupsEnabled,
JWTGroupsClaimName: s.JWTGroupsClaimName, JWTGroupsClaimName: s.JWTGroupsClaimName,
GroupsPropagationEnabled: s.GroupsPropagationEnabled, GroupsPropagationEnabled: s.GroupsPropagationEnabled,
} }
if s.Extra != nil {
settings.Extra = s.Extra.Copy()
}
return settings
}
type ExtraSettings struct {
// PeerApprovalEnabled enables or disables the need for peers bo be approved by an administrator
PeerApprovalEnabled bool
}
// Copy copies the ExtraSettings struct
func (e *ExtraSettings) Copy() *ExtraSettings {
return &ExtraSettings{
PeerApprovalEnabled: e.PeerApprovalEnabled,
}
} }
// Account represents a unique account of the system // Account represents a unique account of the system
@ -193,8 +205,8 @@ type Account struct {
SetupKeys map[string]*SetupKey `gorm:"-"` SetupKeys map[string]*SetupKey `gorm:"-"`
SetupKeysG []SetupKey `json:"-" gorm:"foreignKey:AccountID;references:id"` SetupKeysG []SetupKey `json:"-" gorm:"foreignKey:AccountID;references:id"`
Network *Network `gorm:"embedded;embeddedPrefix:network_"` Network *Network `gorm:"embedded;embeddedPrefix:network_"`
Peers map[string]*Peer `gorm:"-"` Peers map[string]*nbpeer.Peer `gorm:"-"`
PeersG []Peer `json:"-" gorm:"foreignKey:AccountID;references:id"` PeersG []nbpeer.Peer `json:"-" gorm:"foreignKey:AccountID;references:id"`
Users map[string]*User `gorm:"-"` Users map[string]*User `gorm:"-"`
UsersG []User `json:"-" gorm:"foreignKey:AccountID;references:id"` UsersG []User `json:"-" gorm:"foreignKey:AccountID;references:id"`
Groups map[string]*Group `gorm:"-"` Groups map[string]*Group `gorm:"-"`
@ -229,7 +241,7 @@ type UserInfo struct {
// getRoutesToSync returns the enabled routes for the peer ID and the routes // getRoutesToSync returns the enabled routes for the peer ID and the routes
// from the ACL peers that have distribution groups associated with the peer ID. // from the ACL peers that have distribution groups associated with the peer ID.
// Please mind, that the returned route.Route objects will contain Peer.Key instead of Peer.ID. // Please mind, that the returned route.Route objects will contain Peer.Key instead of Peer.ID.
func (a *Account) getRoutesToSync(peerID string, aclPeers []*Peer) []*route.Route { func (a *Account) getRoutesToSync(peerID string, aclPeers []*nbpeer.Peer) []*route.Route {
routes, peerDisabledRoutes := a.getRoutingPeerRoutes(peerID) routes, peerDisabledRoutes := a.getRoutingPeerRoutes(peerID)
peerRoutesMembership := make(lookupMap) peerRoutesMembership := make(lookupMap)
for _, r := range append(routes, peerDisabledRoutes...) { for _, r := range append(routes, peerDisabledRoutes...) {
@ -359,7 +371,7 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string) *NetworkMap {
Network: a.Network.Copy(), Network: a.Network.Copy(),
} }
} }
validatedPeers := integrations.ValidatePeers([]*Peer{peer}, a) validatedPeers := integrations.ValidatePeers([]*nbpeer.Peer{peer}, a)
if len(validatedPeers) == 0 { if len(validatedPeers) == 0 {
return &NetworkMap{ return &NetworkMap{
Network: a.Network.Copy(), Network: a.Network.Copy(),
@ -368,8 +380,8 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string) *NetworkMap {
aclPeers, firewallRules := a.getPeerConnectionResources(peerID) aclPeers, firewallRules := a.getPeerConnectionResources(peerID)
aclPeers = integrations.ValidatePeers(aclPeers, a) aclPeers = integrations.ValidatePeers(aclPeers, a)
// exclude expired peers // exclude expired peers
var peersToConnect []*Peer var peersToConnect []*nbpeer.Peer
var expiredPeers []*Peer var expiredPeers []*nbpeer.Peer
for _, p := range aclPeers { for _, p := range aclPeers {
expired, _ := p.LoginExpired(a.Settings.PeerLoginExpiration) expired, _ := p.LoginExpired(a.Settings.PeerLoginExpiration)
if a.Settings.PeerLoginExpirationEnabled && expired { if a.Settings.PeerLoginExpirationEnabled && expired {
@ -407,8 +419,8 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string) *NetworkMap {
} }
// GetExpiredPeers returns peers that have been expired // GetExpiredPeers returns peers that have been expired
func (a *Account) GetExpiredPeers() []*Peer { func (a *Account) GetExpiredPeers() []*nbpeer.Peer {
var peers []*Peer var peers []*nbpeer.Peer
for _, peer := range a.GetPeersWithExpiration() { for _, peer := range a.GetPeersWithExpiration() {
expired, _ := peer.LoginExpired(a.Settings.PeerLoginExpiration) expired, _ := peer.LoginExpired(a.Settings.PeerLoginExpiration)
if expired { if expired {
@ -447,8 +459,8 @@ func (a *Account) GetNextPeerExpiration() (time.Duration, bool) {
} }
// GetPeersWithExpiration returns a list of peers that have Peer.LoginExpirationEnabled set to true and that were added by a user // GetPeersWithExpiration returns a list of peers that have Peer.LoginExpirationEnabled set to true and that were added by a user
func (a *Account) GetPeersWithExpiration() []*Peer { func (a *Account) GetPeersWithExpiration() []*nbpeer.Peer {
peers := make([]*Peer, 0) peers := make([]*nbpeer.Peer, 0)
for _, peer := range a.Peers { for _, peer := range a.Peers {
if peer.LoginExpirationEnabled && peer.AddedWithSSOLogin() { if peer.LoginExpirationEnabled && peer.AddedWithSSOLogin() {
peers = append(peers, peer) peers = append(peers, peer)
@ -458,8 +470,8 @@ func (a *Account) GetPeersWithExpiration() []*Peer {
} }
// GetPeers returns a list of all Account peers // GetPeers returns a list of all Account peers
func (a *Account) GetPeers() []*Peer { func (a *Account) GetPeers() []*nbpeer.Peer {
var peers []*Peer var peers []*nbpeer.Peer
for _, peer := range a.Peers { for _, peer := range a.Peers {
peers = append(peers, peer) peers = append(peers, peer)
} }
@ -473,7 +485,7 @@ func (a *Account) UpdateSettings(update *Settings) *Account {
} }
// UpdatePeer saves new or replaces existing peer // UpdatePeer saves new or replaces existing peer
func (a *Account) UpdatePeer(update *Peer) { func (a *Account) UpdatePeer(update *nbpeer.Peer) {
a.Peers[update.ID] = update a.Peers[update.ID] = update
} }
@ -502,7 +514,7 @@ func (a *Account) DeletePeer(peerID string) {
// FindPeerByPubKey looks for a Peer by provided WireGuard public key in the Account or returns error if it wasn't found. // FindPeerByPubKey looks for a Peer by provided WireGuard public key in the Account or returns error if it wasn't found.
// It will return an object copy of the peer. // It will return an object copy of the peer.
func (a *Account) FindPeerByPubKey(peerPubKey string) (*Peer, error) { func (a *Account) FindPeerByPubKey(peerPubKey string) (*nbpeer.Peer, error) {
for _, peer := range a.Peers { for _, peer := range a.Peers {
if peer.Key == peerPubKey { if peer.Key == peerPubKey {
return peer.Copy(), nil return peer.Copy(), nil
@ -513,8 +525,8 @@ func (a *Account) FindPeerByPubKey(peerPubKey string) (*Peer, error) {
} }
// FindUserPeers returns a list of peers that user owns (created) // FindUserPeers returns a list of peers that user owns (created)
func (a *Account) FindUserPeers(userID string) ([]*Peer, error) { func (a *Account) FindUserPeers(userID string) ([]*nbpeer.Peer, error) {
peers := make([]*Peer, 0) peers := make([]*nbpeer.Peer, 0)
for _, peer := range a.Peers { for _, peer := range a.Peers {
if peer.UserID == userID { if peer.UserID == userID {
peers = append(peers, peer) peers = append(peers, peer)
@ -606,7 +618,7 @@ func (a *Account) getPeerDNSLabels() lookupMap {
} }
func (a *Account) Copy() *Account { func (a *Account) Copy() *Account {
peers := map[string]*Peer{} peers := map[string]*nbpeer.Peer{}
for id, peer := range a.Peers { for id, peer := range a.Peers {
peers[id] = peer.Copy() peers[id] = peer.Copy()
} }
@ -683,7 +695,7 @@ func (a *Account) GetGroupAll() (*Group, error) {
} }
// GetPeer looks up a Peer by ID // GetPeer looks up a Peer by ID
func (a *Account) GetPeer(peerID string) *Peer { func (a *Account) GetPeer(peerID string) *nbpeer.Peer {
return a.Peers[peerID] return a.Peers[peerID]
} }
@ -893,7 +905,7 @@ func (am *DefaultAccountManager) UpdateAccountSettings(accountID, userID string,
return nil, err return nil, err
} }
err = integrations.ValidateExtraSettings(newSettings.Extra, account, am) err = integrations.ValidateExtraSettings(newSettings.Extra, account, userID, am)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -924,18 +936,6 @@ func (am *DefaultAccountManager) UpdateAccountSettings(accountID, userID string,
am.checkAndSchedulePeerLoginExpiration(account) am.checkAndSchedulePeerLoginExpiration(account)
} }
// if oldSettings.PeerApprovalEnabled != newSettings.PeerApprovalEnabled {
// event := activity.AccountPeerApprovalEnabled
// if !newSettings.PeerApprovalEnabled {
// event = activity.AccountPeerApprovalDisabled
// }
// am.StoreEvent(userID, accountID, accountID, event, nil)
//
// for _, peer := range account.Peers {
// peer.Status.RequiresApproval = false
// }
// }
updatedAccount := account.UpdateSettings(newSettings) updatedAccount := account.UpdateSettings(newSettings)
err = am.Store.SaveAccount(account) err = am.Store.SaveAccount(account)
@ -1683,7 +1683,7 @@ func newAccountWithId(accountID, userID, domain string) *Account {
log.Debugf("creating new account") log.Debugf("creating new account")
network := NewNetwork() network := NewNetwork()
peers := make(map[string]*Peer) peers := make(map[string]*nbpeer.Peer)
users := make(map[string]*User) users := make(map[string]*User)
routes := make(map[string]*route.Route) routes := make(map[string]*route.Route)
setupKeys := map[string]*SetupKey{} setupKeys := map[string]*SetupKey{}

View File

@ -15,6 +15,7 @@ import (
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/route" "github.com/netbirdio/netbird/route"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -26,10 +27,10 @@ import (
func verifyCanAddPeerToAccount(t *testing.T, manager AccountManager, account *Account, userID string) { func verifyCanAddPeerToAccount(t *testing.T, manager AccountManager, account *Account, userID string) {
t.Helper() t.Helper()
peer := &Peer{ peer := &nbpeer.Peer{
Key: "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8=", Key: "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8=",
Name: "test-host@netbird.io", Name: "test-host@netbird.io",
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host@netbird.io", Hostname: "test-host@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -110,13 +111,14 @@ func verifyNewAccountHasDefaultFields(t *testing.T, account *Account, createdBy
func TestAccount_GetPeerNetworkMap(t *testing.T) { func TestAccount_GetPeerNetworkMap(t *testing.T) {
peerID1 := "peer-1" peerID1 := "peer-1"
peerID2 := "peer-2" peerID2 := "peer-2"
// peerID3 := "peer-3"
tt := []struct { tt := []struct {
name string name string
accountSettings Settings accountSettings Settings
peerID string peerID string
expectedPeers []string expectedPeers []string
expectedOfflinePeers []string expectedOfflinePeers []string
peers map[string]*Peer peers map[string]*nbpeer.Peer
}{ }{
{ {
name: "Should return ALL peers when global peer login expiration disabled", name: "Should return ALL peers when global peer login expiration disabled",
@ -124,14 +126,14 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
peerID: peerID1, peerID: peerID1,
expectedPeers: []string{peerID2}, expectedPeers: []string{peerID2},
expectedOfflinePeers: []string{}, expectedOfflinePeers: []string{},
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
ID: peerID1, ID: peerID1,
Key: "peer-1-key", Key: "peer-1-key",
IP: net.IP{100, 64, 0, 1}, IP: net.IP{100, 64, 0, 1},
Name: peerID1, Name: peerID1,
DNSLabel: peerID1, DNSLabel: peerID1,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: false, Connected: false,
LoginExpired: true, LoginExpired: true,
@ -145,7 +147,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
IP: net.IP{100, 64, 0, 1}, IP: net.IP{100, 64, 0, 1},
Name: peerID2, Name: peerID2,
DNSLabel: peerID2, DNSLabel: peerID2,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: false, Connected: false,
LoginExpired: false, LoginExpired: false,
@ -162,14 +164,14 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
peerID: peerID1, peerID: peerID1,
expectedPeers: []string{}, expectedPeers: []string{},
expectedOfflinePeers: []string{peerID2}, expectedOfflinePeers: []string{peerID2},
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
ID: peerID1, ID: peerID1,
Key: "peer-1-key", Key: "peer-1-key",
IP: net.IP{100, 64, 0, 1}, IP: net.IP{100, 64, 0, 1},
Name: peerID1, Name: peerID1,
DNSLabel: peerID1, DNSLabel: peerID1,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: false, Connected: false,
LoginExpired: true, LoginExpired: true,
@ -184,7 +186,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
IP: net.IP{100, 64, 0, 1}, IP: net.IP{100, 64, 0, 1},
Name: peerID2, Name: peerID2,
DNSLabel: peerID2, DNSLabel: peerID2,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: false, Connected: false,
LoginExpired: true, LoginExpired: true,
@ -195,6 +197,159 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
}, },
}, },
}, },
// {
// name: "Should return only peers that are approved when peer approval is enabled",
// accountSettings: Settings{PeerApprovalEnabled: true},
// peerID: peerID1,
// expectedPeers: []string{peerID3},
// expectedOfflinePeers: []string{},
// peers: map[string]*Peer{
// "peer-1": {
// ID: peerID1,
// Key: "peer-1-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID1,
// DNSLabel: peerID1,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-2": {
// ID: peerID2,
// Key: "peer-2-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID2,
// DNSLabel: peerID2,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: false,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-3": {
// ID: peerID3,
// Key: "peer-3-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID3,
// DNSLabel: peerID3,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// },
// },
// {
// name: "Should return all peers when peer approval is disabled",
// accountSettings: Settings{PeerApprovalEnabled: false},
// peerID: peerID1,
// expectedPeers: []string{peerID2, peerID3},
// expectedOfflinePeers: []string{},
// peers: map[string]*Peer{
// "peer-1": {
// ID: peerID1,
// Key: "peer-1-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID1,
// DNSLabel: peerID1,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-2": {
// ID: peerID2,
// Key: "peer-2-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID2,
// DNSLabel: peerID2,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: false,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-3": {
// ID: peerID3,
// Key: "peer-3-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID3,
// DNSLabel: peerID3,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// },
// },
// {
// name: "Should return no peers when peer approval is enabled and the requesting peer is not approved",
// accountSettings: Settings{PeerApprovalEnabled: true},
// peerID: peerID1,
// expectedPeers: []string{},
// expectedOfflinePeers: []string{},
// peers: map[string]*Peer{
// "peer-1": {
// ID: peerID1,
// Key: "peer-1-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID1,
// DNSLabel: peerID1,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: false,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-2": {
// ID: peerID2,
// Key: "peer-2-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID2,
// DNSLabel: peerID2,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// "peer-3": {
// ID: peerID3,
// Key: "peer-3-key",
// IP: net.IP{100, 64, 0, 1},
// Name: peerID3,
// DNSLabel: peerID3,
// Status: &PeerStatus{
// LastSeen: time.Now().UTC(),
// Connected: false,
// Approved: true,
// },
// UserID: userID,
// LastLogin: time.Now().UTC().Add(-time.Hour * 24 * 30 * 30),
// },
// },
// },
} }
netIP := net.IP{100, 64, 0, 0} netIP := net.IP{100, 64, 0, 0}
@ -209,6 +364,7 @@ func TestAccount_GetPeerNetworkMap(t *testing.T) {
for _, testCase := range tt { for _, testCase := range tt {
account := newAccountWithId("account-1", userID, "netbird.io") account := newAccountWithId("account-1", userID, "netbird.io")
account.UpdateSettings(&testCase.accountSettings)
account.Network = network account.Network = network
account.Peers = testCase.peers account.Peers = testCase.peers
for _, peer := range account.Peers { for _, peer := range account.Peers {
@ -780,9 +936,9 @@ func TestAccountManager_AddPeer(t *testing.T) {
expectedPeerKey := key.PublicKey().String() expectedPeerKey := key.PublicKey().String()
expectedSetupKey := setupKey.Key expectedSetupKey := setupKey.Key
peer, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: expectedPeerKey, Key: expectedPeerKey,
Meta: PeerSystemMeta{Hostname: expectedPeerKey}, Meta: nbpeer.PeerSystemMeta{Hostname: expectedPeerKey},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -848,9 +1004,9 @@ func TestAccountManager_AddPeerWithUserID(t *testing.T) {
expectedPeerKey := key.PublicKey().String() expectedPeerKey := key.PublicKey().String()
expectedUserID := userID expectedUserID := userID
peer, _, err := manager.AddPeer("", userID, &Peer{ peer, _, err := manager.AddPeer("", userID, &nbpeer.Peer{
Key: expectedPeerKey, Key: expectedPeerKey,
Meta: PeerSystemMeta{Hostname: expectedPeerKey}, Meta: nbpeer.PeerSystemMeta{Hostname: expectedPeerKey},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v, account users: %v", err, account.CreatedBy) t.Errorf("expecting peer to be added, got failure %v, account users: %v", err, account.CreatedBy)
@ -915,7 +1071,7 @@ func TestAccountManager_NetworkUpdates(t *testing.T) {
return return
} }
getPeer := func() *Peer { getPeer := func() *nbpeer.Peer {
key, err := wgtypes.GeneratePrivateKey() key, err := wgtypes.GeneratePrivateKey()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -923,9 +1079,9 @@ func TestAccountManager_NetworkUpdates(t *testing.T) {
} }
expectedPeerKey := key.PublicKey().String() expectedPeerKey := key.PublicKey().String()
peer, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: expectedPeerKey, Key: expectedPeerKey,
Meta: PeerSystemMeta{Hostname: expectedPeerKey}, Meta: nbpeer.PeerSystemMeta{Hostname: expectedPeerKey},
}) })
if err != nil { if err != nil {
t.Fatalf("expecting peer1 to be added, got failure %v", err) t.Fatalf("expecting peer1 to be added, got failure %v", err)
@ -1097,9 +1253,9 @@ func TestAccountManager_DeletePeer(t *testing.T) {
peerKey := key.PublicKey().String() peerKey := key.PublicKey().String()
peer, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey, Key: peerKey,
Meta: PeerSystemMeta{Hostname: peerKey}, Meta: nbpeer.PeerSystemMeta{Hostname: peerKey},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -1238,8 +1394,8 @@ func TestAccount_GetRoutesToSync(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peer-1": {Key: "peer-1", Meta: PeerSystemMeta{GoOS: "linux"}}, "peer-2": {Key: "peer-2", Meta: PeerSystemMeta{GoOS: "linux"}}, "peer-3": {Key: "peer-1", Meta: PeerSystemMeta{GoOS: "linux"}}, "peer-1": {Key: "peer-1", Meta: nbpeer.PeerSystemMeta{GoOS: "linux"}}, "peer-2": {Key: "peer-2", Meta: nbpeer.PeerSystemMeta{GoOS: "linux"}}, "peer-3": {Key: "peer-1", Meta: nbpeer.PeerSystemMeta{GoOS: "linux"}},
}, },
Groups: map[string]*Group{"group1": {ID: "group1", Peers: []string{"peer-1", "peer-2"}}}, Groups: map[string]*Group{"group1": {ID: "group1", Peers: []string{"peer-1", "peer-2"}}},
Routes: map[string]*route.Route{ Routes: map[string]*route.Route{
@ -1282,7 +1438,7 @@ func TestAccount_GetRoutesToSync(t *testing.T) {
}, },
} }
routes := account.getRoutesToSync("peer-2", []*Peer{{Key: "peer-1"}, {Key: "peer-3"}}) routes := account.getRoutesToSync("peer-2", []*nbpeer.Peer{{Key: "peer-1"}, {Key: "peer-3"}})
assert.Len(t, routes, 2) assert.Len(t, routes, 2)
routeIDs := make(map[string]struct{}, 2) routeIDs := make(map[string]struct{}, 2)
@ -1292,7 +1448,7 @@ func TestAccount_GetRoutesToSync(t *testing.T) {
assert.Contains(t, routeIDs, "route-2") assert.Contains(t, routeIDs, "route-2")
assert.Contains(t, routeIDs, "route-3") assert.Contains(t, routeIDs, "route-3")
emptyRoutes := account.getRoutesToSync("peer-3", []*Peer{{Key: "peer-1"}, {Key: "peer-2"}}) emptyRoutes := account.getRoutesToSync("peer-3", []*nbpeer.Peer{{Key: "peer-1"}, {Key: "peer-2"}})
assert.Len(t, emptyRoutes, 0) assert.Len(t, emptyRoutes, 0)
} }
@ -1313,10 +1469,10 @@ func TestAccount_Copy(t *testing.T) {
Network: &Network{ Network: &Network{
Identifier: "net1", Identifier: "net1",
}, },
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peer1": { "peer1": {
Key: "key1", Key: "key1",
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now(), LastSeen: time.Now(),
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
@ -1443,9 +1599,9 @@ func TestDefaultAccountManager_UpdatePeer_PeerLoginExpiration(t *testing.T) {
key, err := wgtypes.GenerateKey() key, err := wgtypes.GenerateKey()
require.NoError(t, err, "unable to generate WireGuard key") require.NoError(t, err, "unable to generate WireGuard key")
peer, _, err := manager.AddPeer("", userID, &Peer{ peer, _, err := manager.AddPeer("", userID, &nbpeer.Peer{
Key: key.PublicKey().String(), Key: key.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer"},
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
}) })
require.NoError(t, err, "unable to add peer") require.NoError(t, err, "unable to add peer")
@ -1492,9 +1648,9 @@ func TestDefaultAccountManager_MarkPeerConnected_PeerLoginExpiration(t *testing.
key, err := wgtypes.GenerateKey() key, err := wgtypes.GenerateKey()
require.NoError(t, err, "unable to generate WireGuard key") require.NoError(t, err, "unable to generate WireGuard key")
_, _, err = manager.AddPeer("", userID, &Peer{ _, _, err = manager.AddPeer("", userID, &nbpeer.Peer{
Key: key.PublicKey().String(), Key: key.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer"},
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
}) })
require.NoError(t, err, "unable to add peer") require.NoError(t, err, "unable to add peer")
@ -1533,9 +1689,9 @@ func TestDefaultAccountManager_UpdateAccountSettings_PeerLoginExpiration(t *test
key, err := wgtypes.GenerateKey() key, err := wgtypes.GenerateKey()
require.NoError(t, err, "unable to generate WireGuard key") require.NoError(t, err, "unable to generate WireGuard key")
_, _, err = manager.AddPeer("", userID, &Peer{ _, _, err = manager.AddPeer("", userID, &nbpeer.Peer{
Key: key.PublicKey().String(), Key: key.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer"},
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
}) })
require.NoError(t, err, "unable to add peer") require.NoError(t, err, "unable to add peer")
@ -1614,13 +1770,13 @@ func TestDefaultAccountManager_UpdateAccountSettings(t *testing.T) {
func TestAccount_GetExpiredPeers(t *testing.T) { func TestAccount_GetExpiredPeers(t *testing.T) {
type test struct { type test struct {
name string name string
peers map[string]*Peer peers map[string]*nbpeer.Peer
expectedPeers map[string]struct{} expectedPeers map[string]struct{}
} }
testCases := []test{ testCases := []test{
{ {
name: "Peers with login expiration disabled, no expired peers", name: "Peers with login expiration disabled, no expired peers",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
}, },
@ -1632,11 +1788,11 @@ func TestAccount_GetExpiredPeers(t *testing.T) {
}, },
{ {
name: "Two peers expired", name: "Two peers expired",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
ID: "peer-1", ID: "peer-1",
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
@ -1647,7 +1803,7 @@ func TestAccount_GetExpiredPeers(t *testing.T) {
"peer-2": { "peer-2": {
ID: "peer-2", ID: "peer-2",
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
@ -1659,7 +1815,7 @@ func TestAccount_GetExpiredPeers(t *testing.T) {
"peer-3": { "peer-3": {
ID: "peer-3", ID: "peer-3",
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
LastSeen: time.Now().UTC(), LastSeen: time.Now().UTC(),
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
@ -1699,19 +1855,19 @@ func TestAccount_GetExpiredPeers(t *testing.T) {
func TestAccount_GetPeersWithExpiration(t *testing.T) { func TestAccount_GetPeersWithExpiration(t *testing.T) {
type test struct { type test struct {
name string name string
peers map[string]*Peer peers map[string]*nbpeer.Peer
expectedPeers map[string]struct{} expectedPeers map[string]struct{}
} }
testCases := []test{ testCases := []test{
{ {
name: "No account peers, no peers with expiration", name: "No account peers, no peers with expiration",
peers: map[string]*Peer{}, peers: map[string]*nbpeer.Peer{},
expectedPeers: map[string]struct{}{}, expectedPeers: map[string]struct{}{},
}, },
{ {
name: "Peers with login expiration disabled, no peers with expiration", name: "Peers with login expiration disabled, no peers with expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
UserID: userID, UserID: userID,
@ -1725,7 +1881,7 @@ func TestAccount_GetPeersWithExpiration(t *testing.T) {
}, },
{ {
name: "Peers with login expiration enabled, return peers with expiration", name: "Peers with login expiration enabled, return peers with expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
ID: "peer-1", ID: "peer-1",
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
@ -1768,7 +1924,7 @@ func TestAccount_GetPeersWithExpiration(t *testing.T) {
func TestAccount_GetNextPeerExpiration(t *testing.T) { func TestAccount_GetNextPeerExpiration(t *testing.T) {
type test struct { type test struct {
name string name string
peers map[string]*Peer peers map[string]*nbpeer.Peer
expiration time.Duration expiration time.Duration
expirationEnabled bool expirationEnabled bool
expectedNextRun bool expectedNextRun bool
@ -1779,7 +1935,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
testCases := []test{ testCases := []test{
{ {
name: "No peers, no expiration", name: "No peers, no expiration",
peers: map[string]*Peer{}, peers: map[string]*nbpeer.Peer{},
expiration: time.Second, expiration: time.Second,
expirationEnabled: false, expirationEnabled: false,
expectedNextRun: false, expectedNextRun: false,
@ -1787,16 +1943,16 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
}, },
{ {
name: "No connected peers, no expiration", name: "No connected peers, no expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: false, Connected: false,
}, },
LoginExpirationEnabled: true, LoginExpirationEnabled: true,
UserID: userID, UserID: userID,
}, },
"peer-2": { "peer-2": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
}, },
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
@ -1810,16 +1966,16 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
}, },
{ {
name: "Connected peers with disabled expiration, no expiration", name: "Connected peers with disabled expiration, no expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
}, },
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
UserID: userID, UserID: userID,
}, },
"peer-2": { "peer-2": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
}, },
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
@ -1833,9 +1989,9 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
}, },
{ {
name: "Expired peers, no expiration", name: "Expired peers, no expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: true, LoginExpired: true,
}, },
@ -1843,7 +1999,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
UserID: userID, UserID: userID,
}, },
"peer-2": { "peer-2": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: true, LoginExpired: true,
}, },
@ -1858,9 +2014,9 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
}, },
{ {
name: "To be expired peer, return expiration", name: "To be expired peer, return expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
}, },
@ -1869,7 +2025,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
UserID: userID, UserID: userID,
}, },
"peer-2": { "peer-2": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: true, LoginExpired: true,
}, },
@ -1884,9 +2040,9 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
}, },
{ {
name: "Peers added with setup keys, no expiration", name: "Peers added with setup keys, no expiration",
peers: map[string]*Peer{ peers: map[string]*nbpeer.Peer{
"peer-1": { "peer-1": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
}, },
@ -1894,7 +2050,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
SetupKey: "key", SetupKey: "key",
}, },
"peer-2": { "peer-2": {
Status: &PeerStatus{ Status: &nbpeer.PeerStatus{
Connected: true, Connected: true,
LoginExpired: false, LoginExpired: false,
}, },
@ -1929,7 +2085,7 @@ func TestAccount_GetNextPeerExpiration(t *testing.T) {
func TestAccount_SetJWTGroups(t *testing.T) { func TestAccount_SetJWTGroups(t *testing.T) {
// create a new account // create a new account
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"}, "peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"}, "peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"}, "peer3": {ID: "peer3", Key: "key3", UserID: "user1"},
@ -1977,7 +2133,7 @@ func TestAccount_SetJWTGroups(t *testing.T) {
func TestAccount_UserGroupsAddToPeers(t *testing.T) { func TestAccount_UserGroupsAddToPeers(t *testing.T) {
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"}, "peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"}, "peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"}, "peer3": {ID: "peer3", Key: "key3", UserID: "user1"},
@ -2013,7 +2169,7 @@ func TestAccount_UserGroupsAddToPeers(t *testing.T) {
func TestAccount_UserGroupsRemoveFromPeers(t *testing.T) { func TestAccount_UserGroupsRemoveFromPeers(t *testing.T) {
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peer1": {ID: "peer1", Key: "key1", UserID: "user1"}, "peer1": {ID: "peer1", Key: "key1", UserID: "user1"},
"peer2": {ID: "peer2", Key: "key2", UserID: "user1"}, "peer2": {ID: "peer2", Key: "key2", UserID: "user1"},
"peer3": {ID: "peer3", Key: "key3", UserID: "user1"}, "peer3": {ID: "peer3", Key: "key3", UserID: "user1"},

View File

@ -10,6 +10,7 @@ import (
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
) )
@ -200,7 +201,7 @@ func getPeerNSGroups(account *Account, peerID string) []*nbdns.NameServerGroup {
} }
// peerIsNameserver returns true if the peer is a nameserver for a nsGroup // peerIsNameserver returns true if the peer is a nameserver for a nsGroup
func peerIsNameserver(peer *Peer, nsGroup *nbdns.NameServerGroup) bool { func peerIsNameserver(peer *nbpeer.Peer, nsGroup *nbdns.NameServerGroup) bool {
for _, ns := range nsGroup.NameServers { for _, ns := range nsGroup.NameServers {
if peer.IP.Equal(ns.IP.AsSlice()) { if peer.IP.Equal(ns.IP.AsSlice()) {
return true return true

View File

@ -8,6 +8,7 @@ import (
"github.com/netbirdio/netbird/dns" "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
) )
@ -208,10 +209,10 @@ func createDNSStore(t *testing.T) (Store, error) {
func initTestDNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) { func initTestDNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) {
t.Helper() t.Helper()
peer1 := &Peer{ peer1 := &nbpeer.Peer{
Key: dnsPeer1Key, Key: dnsPeer1Key,
Name: "test-host1@netbird.io", Name: "test-host1@netbird.io",
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host1@netbird.io", Hostname: "test-host1@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -223,10 +224,10 @@ func initTestDNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, erro
}, },
DNSLabel: dnsPeer1Key, DNSLabel: dnsPeer1Key,
} }
peer2 := &Peer{ peer2 := &nbpeer.Peer{
Key: dnsPeer2Key, Key: dnsPeer2Key,
Name: "test-host2@netbird.io", Name: "test-host2@netbird.io",
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host2@netbird.io", Hostname: "test-host2@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",

View File

@ -7,6 +7,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
) )
const ( const (
@ -72,7 +73,7 @@ func (e *EphemeralManager) Stop() {
// OnPeerConnected remove the peer from the linked list of ephemeral peers. Because it has been called when the peer // OnPeerConnected remove the peer from the linked list of ephemeral peers. Because it has been called when the peer
// is active the manager will not delete it while it is active. // is active the manager will not delete it while it is active.
func (e *EphemeralManager) OnPeerConnected(peer *Peer) { func (e *EphemeralManager) OnPeerConnected(peer *nbpeer.Peer) {
if !peer.Ephemeral { if !peer.Ephemeral {
return return
} }
@ -93,7 +94,7 @@ func (e *EphemeralManager) OnPeerConnected(peer *Peer) {
// OnPeerDisconnected add the peer to the linked list of ephemeral peers. Because of the peer // OnPeerDisconnected add the peer to the linked list of ephemeral peers. Because of the peer
// is inactive it will be deleted after the ephemeralLifeTime period. // is inactive it will be deleted after the ephemeralLifeTime period.
func (e *EphemeralManager) OnPeerDisconnected(peer *Peer) { func (e *EphemeralManager) OnPeerDisconnected(peer *nbpeer.Peer) {
if !peer.Ephemeral { if !peer.Ephemeral {
return return
} }

View File

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"testing" "testing"
"time" "time"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
) )
type MockStore struct { type MockStore struct {
@ -124,7 +126,7 @@ func seedPeers(store *MockStore, numberOfPeers int, numberOfEphemeralPeers int)
for i := 0; i < numberOfPeers; i++ { for i := 0; i < numberOfPeers; i++ {
peerId := fmt.Sprintf("peer_%d", i) peerId := fmt.Sprintf("peer_%d", i)
p := &Peer{ p := &nbpeer.Peer{
ID: peerId, ID: peerId,
Ephemeral: false, Ephemeral: false,
} }
@ -133,7 +135,7 @@ func seedPeers(store *MockStore, numberOfPeers int, numberOfEphemeralPeers int)
for i := 0; i < numberOfEphemeralPeers; i++ { for i := 0; i < numberOfEphemeralPeers; i++ {
peerId := fmt.Sprintf("ephemeral_peer_%d", i) peerId := fmt.Sprintf("ephemeral_peer_%d", i)
p := &Peer{ p := &nbpeer.Peer{
ID: peerId, ID: peerId,
Ephemeral: true, Ephemeral: true,
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/rs/xid" "github.com/rs/xid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/telemetry" "github.com/netbirdio/netbird/management/server/telemetry"
@ -204,7 +205,7 @@ func restore(file string) (*FileStore, error) {
// Set the Peer.ID to the newly generated value. // Set the Peer.ID to the newly generated value.
// Replace all the mentions of Peer.Key as ID (groups and routes). // Replace all the mentions of Peer.Key as ID (groups and routes).
// Swap Peer.Key with Peer.ID in the Account.Peers map. // Swap Peer.Key with Peer.ID in the Account.Peers map.
migrationPeers := make(map[string]*Peer) // key to Peer migrationPeers := make(map[string]*nbpeer.Peer) // key to Peer
for key, peer := range account.Peers { for key, peer := range account.Peers {
// set LastLogin for the peers that were onboarded before the peer login expiration feature // set LastLogin for the peers that were onboarded before the peer login expiration feature
if peer.LastLogin.IsZero() { if peer.LastLogin.IsZero() {
@ -571,7 +572,7 @@ func (s *FileStore) SaveInstallationID(ID string) error {
// SavePeerStatus stores the PeerStatus in memory. It doesn't attempt to persist data to speed up things. // SavePeerStatus stores the PeerStatus in memory. It doesn't attempt to persist data to speed up things.
// PeerStatus will be saved eventually when some other changes occur. // PeerStatus will be saved eventually when some other changes occur.
func (s *FileStore) SavePeerStatus(accountID, peerID string, peerStatus PeerStatus) error { func (s *FileStore) SavePeerStatus(accountID, peerID string, peerStatus nbpeer.PeerStatus) error {
s.mux.Lock() s.mux.Lock()
defer s.mux.Unlock() defer s.mux.Unlock()

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/util" "github.com/netbirdio/netbird/util"
) )
@ -35,7 +36,7 @@ func TestStalePeerIndices(t *testing.T) {
peerID := "some_peer" peerID := "some_peer"
peerKey := "some_peer_key" peerKey := "some_peer_key"
account.Peers[peerID] = &Peer{ account.Peers[peerID] = &nbpeer.Peer{
ID: peerID, ID: peerID,
Key: peerKey, Key: peerKey,
} }
@ -89,13 +90,13 @@ func TestSaveAccount(t *testing.T) {
account := newAccountWithId("account_id", "testuser", "") account := newAccountWithId("account_id", "testuser", "")
setupKey := GenerateDefaultSetupKey() setupKey := GenerateDefaultSetupKey()
account.SetupKeys[setupKey.Key] = setupKey account.SetupKeys[setupKey.Key] = setupKey
account.Peers["testpeer"] = &Peer{ account.Peers["testpeer"] = &nbpeer.Peer{
Key: "peerkey", Key: "peerkey",
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: true, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
} }
// SaveAccount should trigger persist // SaveAccount should trigger persist
@ -125,13 +126,13 @@ func TestStore(t *testing.T) {
store := newStore(t) store := newStore(t)
account := newAccountWithId("account_id", "testuser", "") account := newAccountWithId("account_id", "testuser", "")
account.Peers["testpeer"] = &Peer{ account.Peers["testpeer"] = &nbpeer.Peer{
Key: "peerkey", Key: "peerkey",
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: true, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
} }
account.Groups["all"] = &Group{ account.Groups["all"] = &Group{
ID: "all", ID: "all",
@ -546,19 +547,19 @@ func TestFileStore_SavePeerStatus(t *testing.T) {
} }
// save status of non-existing peer // save status of non-existing peer
newStatus := PeerStatus{Connected: true, LastSeen: time.Now().UTC()} newStatus := nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()}
err = store.SavePeerStatus(account.Id, "non-existing-peer", newStatus) err = store.SavePeerStatus(account.Id, "non-existing-peer", newStatus)
assert.Error(t, err) assert.Error(t, err)
// save new status of existing peer // save new status of existing peer
account.Peers["testpeer"] = &Peer{ account.Peers["testpeer"] = &nbpeer.Peer{
Key: "peerkey", Key: "peerkey",
ID: "testpeer", ID: "testpeer",
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: false, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now().UTC()},
} }
err = store.SaveAccount(account) err = store.SaveAccount(account)

View File

@ -17,6 +17,7 @@ import (
"github.com/netbirdio/netbird/encryption" "github.com/netbirdio/netbird/encryption"
"github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
internalStatus "github.com/netbirdio/netbird/management/server/status" internalStatus "github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/telemetry" "github.com/netbirdio/netbird/management/server/telemetry"
) )
@ -196,7 +197,7 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
} }
} }
func (s *GRPCServer) cancelPeerRoutines(peer *Peer) { func (s *GRPCServer) cancelPeerRoutines(peer *nbpeer.Peer) {
s.peersUpdateManager.CloseChannel(peer.ID) s.peersUpdateManager.CloseChannel(peer.ID)
s.turnCredentialsManager.CancelRefresh(peer.ID) s.turnCredentialsManager.CancelRefresh(peer.ID)
_ = s.accountManager.MarkPeerConnected(peer.Key, false) _ = s.accountManager.MarkPeerConnected(peer.Key, false)
@ -243,8 +244,8 @@ func mapError(err error) error {
return status.Errorf(codes.Internal, "failed handling request") return status.Errorf(codes.Internal, "failed handling request")
} }
func extractPeerMeta(loginReq *proto.LoginRequest) PeerSystemMeta { func extractPeerMeta(loginReq *proto.LoginRequest) nbpeer.PeerSystemMeta {
return PeerSystemMeta{ return nbpeer.PeerSystemMeta{
Hostname: loginReq.GetMeta().GetHostname(), Hostname: loginReq.GetMeta().GetHostname(),
GoOS: loginReq.GetMeta().GetGoOS(), GoOS: loginReq.GetMeta().GetGoOS(),
Kernel: loginReq.GetMeta().GetKernel(), Kernel: loginReq.GetMeta().GetKernel(),
@ -413,7 +414,7 @@ func toWiretrusteeConfig(config *Config, turnCredentials *TURNCredentials) *prot
} }
} }
func toPeerConfig(peer *Peer, network *Network, dnsName string) *proto.PeerConfig { func toPeerConfig(peer *nbpeer.Peer, network *Network, dnsName string) *proto.PeerConfig {
netmask, _ := network.Net.Mask.Size() netmask, _ := network.Net.Mask.Size()
fqdn := peer.FQDN(dnsName) fqdn := peer.FQDN(dnsName)
return &proto.PeerConfig{ return &proto.PeerConfig{
@ -423,7 +424,7 @@ func toPeerConfig(peer *Peer, network *Network, dnsName string) *proto.PeerConfi
} }
} }
func toRemotePeerConfig(peers []*Peer, dnsName string) []*proto.RemotePeerConfig { func toRemotePeerConfig(peers []*nbpeer.Peer, dnsName string) []*proto.RemotePeerConfig {
remotePeers := []*proto.RemotePeerConfig{} remotePeers := []*proto.RemotePeerConfig{}
for _, rPeer := range peers { for _, rPeer := range peers {
fqdn := rPeer.FQDN(dnsName) fqdn := rPeer.FQDN(dnsName)
@ -437,7 +438,7 @@ func toRemotePeerConfig(peers []*Peer, dnsName string) []*proto.RemotePeerConfig
return remotePeers return remotePeers
} }
func toSyncResponse(config *Config, peer *Peer, turnCredentials *TURNCredentials, networkMap *NetworkMap, dnsName string) *proto.SyncResponse { func toSyncResponse(config *Config, peer *nbpeer.Peer, turnCredentials *TURNCredentials, networkMap *NetworkMap, dnsName string) *proto.SyncResponse {
wtConfig := toWiretrusteeConfig(config, turnCredentials) wtConfig := toWiretrusteeConfig(config, turnCredentials)
pConfig := toPeerConfig(peer, networkMap.Network, dnsName) pConfig := toPeerConfig(peer, networkMap.Network, dnsName)
@ -477,7 +478,7 @@ func (s *GRPCServer) IsHealthy(ctx context.Context, req *proto.Empty) (*proto.Em
} }
// sendInitialSync sends initial proto.SyncResponse to the peer requesting synchronization // sendInitialSync sends initial proto.SyncResponse to the peer requesting synchronization
func (s *GRPCServer) sendInitialSync(peerKey wgtypes.Key, peer *Peer, networkMap *NetworkMap, srv proto.ManagementService_SyncServer) error { func (s *GRPCServer) sendInitialSync(peerKey wgtypes.Key, peer *nbpeer.Peer, networkMap *NetworkMap, srv proto.ManagementService_SyncServer) error {
// make secret time based TURN credentials optional // make secret time based TURN credentials optional
var turnCredentials *TURNCredentials var turnCredentials *TURNCredentials
if s.config.TURNConfig.TimeBasedCredentials { if s.config.TURNConfig.TimeBasedCredentials {

View File

@ -61,6 +61,7 @@ func initTestMetaData(peers ...*server.Peer) *PeersHandler {
Domain: "hotmail.com", Domain: "hotmail.com",
Peers: map[string]*server.Peer{ Peers: map[string]*server.Peer{
peers[0].ID: peers[0], peers[0].ID: peers[0],
peers[1].ID: peers[1],
}, },
Users: map[string]*server.User{ Users: map[string]*server.User{
"test_user": user, "test_user": user,
@ -112,7 +113,7 @@ func TestGetPeers(t *testing.T) {
Key: "key", Key: "key",
SetupKey: "setupkey", SetupKey: "setupkey",
IP: net.ParseIP("100.64.0.1"), IP: net.ParseIP("100.64.0.1"),
Status: &server.PeerStatus{Connected: true}, Status: &server.PeerStatus{Connected: true, Approved: true},
Name: "PeerName", Name: "PeerName",
LoginExpirationEnabled: false, LoginExpirationEnabled: false,
Meta: server.PeerSystemMeta{ Meta: server.PeerSystemMeta{

View File

@ -8,6 +8,7 @@ import (
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
) )
const ( const (
@ -763,10 +764,10 @@ func createNSStore(t *testing.T) (Store, error) {
func initTestNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) { func initTestNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) {
t.Helper() t.Helper()
peer1 := &Peer{ peer1 := &nbpeer.Peer{
Key: nsGroupPeer1Key, Key: nsGroupPeer1Key,
Name: "test-host1@netbird.io", Name: "test-host1@netbird.io",
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host1@netbird.io", Hostname: "test-host1@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -777,10 +778,10 @@ func initTestNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, error
UIVersion: "development", UIVersion: "development",
}, },
} }
peer2 := &Peer{ peer2 := &nbpeer.Peer{
Key: nsGroupPeer2Key, Key: nsGroupPeer2Key,
Name: "test-host2@netbird.io", Name: "test-host2@netbird.io",
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host2@netbird.io", Hostname: "test-host2@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",

View File

@ -10,6 +10,7 @@ import (
"github.com/rs/xid" "github.com/rs/xid"
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/route" "github.com/netbirdio/netbird/route"
) )
@ -25,11 +26,11 @@ const (
) )
type NetworkMap struct { type NetworkMap struct {
Peers []*Peer Peers []*nbpeer.Peer
Network *Network Network *Network
Routes []*route.Route Routes []*route.Route
DNSConfig nbdns.Config DNSConfig nbdns.Config
OfflinePeers []*Peer OfflinePeers []*nbpeer.Peer
FirewallRules []*FirewallRule FirewallRules []*FirewallRule
} }

View File

@ -2,7 +2,6 @@ package server
import ( import (
"fmt" "fmt"
"net"
"strings" "strings"
"time" "time"
@ -10,6 +9,7 @@ import (
"github.com/rs/xid" "github.com/rs/xid"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -17,40 +17,6 @@ import (
"github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/proto"
) )
// PeerSystemMeta is a metadata of a Peer machine system
type PeerSystemMeta struct {
Hostname string
GoOS string
Kernel string
Core string
Platform string
OS string
WtVersion string
UIVersion string
}
func (p PeerSystemMeta) isEqual(other PeerSystemMeta) bool {
return p.Hostname == other.Hostname &&
p.GoOS == other.GoOS &&
p.Kernel == other.Kernel &&
p.Core == other.Core &&
p.Platform == other.Platform &&
p.OS == other.OS &&
p.WtVersion == other.WtVersion &&
p.UIVersion == other.UIVersion
}
type PeerStatus struct {
// LastSeen is the last time peer was connected to the management service
LastSeen time.Time
// Connected indicates whether peer is connected to the management service or not
Connected bool
// LoginExpired
LoginExpired bool
// RequiresApproval indicates whether peer requires approval or not
RequiresApproval bool
}
// PeerSync used as a data object between the gRPC API and AccountManager on Sync request. // PeerSync used as a data object between the gRPC API and AccountManager on Sync request.
type PeerSync struct { type PeerSync struct {
// WireGuardPubKey is a peers WireGuard public key // WireGuardPubKey is a peers WireGuard public key
@ -64,147 +30,16 @@ type PeerLogin struct {
// SSHKey is a peer's ssh key. Can be empty (e.g., old version do not provide it, or this feature is disabled) // SSHKey is a peer's ssh key. Can be empty (e.g., old version do not provide it, or this feature is disabled)
SSHKey string SSHKey string
// Meta is the system information passed by peer, must be always present. // Meta is the system information passed by peer, must be always present.
Meta PeerSystemMeta Meta nbpeer.PeerSystemMeta
// UserID indicates that JWT was used to log in, and it was valid. Can be empty when SetupKey is used or auth is not required. // UserID indicates that JWT was used to log in, and it was valid. Can be empty when SetupKey is used or auth is not required.
UserID string UserID string
// SetupKey references to a server.SetupKey to log in. Can be empty when UserID is used or auth is not required. // SetupKey references to a server.SetupKey to log in. Can be empty when UserID is used or auth is not required.
SetupKey string SetupKey string
} }
// Peer represents a machine connected to the network.
// The Peer is a WireGuard peer identified by a public key
type Peer struct {
// ID is an internal ID of the peer
ID string `gorm:"primaryKey"`
// AccountID is a reference to Account that this object belongs
AccountID string `json:"-" gorm:"index;uniqueIndex:idx_peers_account_id_ip"`
// WireGuard public key
Key string `gorm:"index"`
// A setup key this peer was registered with
SetupKey string
// IP address of the Peer
IP net.IP `gorm:"uniqueIndex:idx_peers_account_id_ip"`
// Meta is a Peer system meta data
Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_"`
// Name is peer's name (machine name)
Name string
// DNSLabel is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's
// domain to the peer label. e.g. peer-dns-label.netbird.cloud
DNSLabel string
// Status peer's management connection status
Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_"`
// The user ID that registered the peer
UserID string
// SSHKey is a public SSH key of the peer
SSHKey string
// SSHEnabled indicates whether SSH server is enabled on the peer
SSHEnabled bool
// LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login.
// Works with LastLogin
LoginExpirationEnabled bool
// LastLogin the time when peer performed last login operation
LastLogin time.Time
// Indicate ephemeral peer attribute
Ephemeral bool
}
// AddedWithSSOLogin indicates whether this peer has been added with an SSO login by a user.
func (p *Peer) AddedWithSSOLogin() bool {
return p.UserID != ""
}
// Copy copies Peer object
func (p *Peer) Copy() *Peer {
peerStatus := p.Status
if peerStatus != nil {
peerStatus = p.Status.Copy()
}
return &Peer{
ID: p.ID,
AccountID: p.AccountID,
Key: p.Key,
SetupKey: p.SetupKey,
IP: p.IP,
Meta: p.Meta,
Name: p.Name,
DNSLabel: p.DNSLabel,
Status: peerStatus,
UserID: p.UserID,
SSHKey: p.SSHKey,
SSHEnabled: p.SSHEnabled,
LoginExpirationEnabled: p.LoginExpirationEnabled,
LastLogin: p.LastLogin,
Ephemeral: p.Ephemeral,
}
}
// UpdateMetaIfNew updates peer's system metadata if new information is provided
// returns true if meta was updated, false otherwise
func (p *Peer) UpdateMetaIfNew(meta PeerSystemMeta) bool {
// Avoid overwriting UIVersion if the update was triggered sole by the CLI client
if meta.UIVersion == "" {
meta.UIVersion = p.Meta.UIVersion
}
if p.Meta.isEqual(meta) {
return false
}
p.Meta = meta
return true
}
// MarkLoginExpired marks peer's status expired or not
func (p *Peer) MarkLoginExpired(expired bool) {
newStatus := p.Status.Copy()
newStatus.LoginExpired = expired
if expired {
newStatus.Connected = false
}
p.Status = newStatus
}
// LoginExpired indicates whether the peer's login has expired or not.
// If Peer.LastLogin plus the expiresIn duration has happened already; then login has expired.
// Return true if a login has expired, false otherwise, and time left to expiration (negative when expired).
// Login expiration can be disabled/enabled on a Peer level via Peer.LoginExpirationEnabled property.
// Login expiration can also be disabled/enabled globally on the Account level via Settings.PeerLoginExpirationEnabled.
// Only peers added by interactive SSO login can be expired.
func (p *Peer) LoginExpired(expiresIn time.Duration) (bool, time.Duration) {
if !p.AddedWithSSOLogin() || !p.LoginExpirationEnabled {
return false, 0
}
expiresAt := p.LastLogin.Add(expiresIn)
now := time.Now()
timeLeft := expiresAt.Sub(now)
return timeLeft <= 0, timeLeft
}
// FQDN returns peers FQDN combined of the peer's DNS label and the system's DNS domain
func (p *Peer) FQDN(dnsDomain string) string {
if dnsDomain == "" {
return ""
}
return fmt.Sprintf("%s.%s", p.DNSLabel, dnsDomain)
}
// EventMeta returns activity event meta related to the peer
func (p *Peer) EventMeta(dnsDomain string) map[string]any {
return map[string]any{"name": p.Name, "fqdn": p.FQDN(dnsDomain), "ip": p.IP}
}
// Copy PeerStatus
func (p *PeerStatus) Copy() *PeerStatus {
return &PeerStatus{
LastSeen: p.LastSeen,
Connected: p.Connected,
LoginExpired: p.LoginExpired,
RequiresApproval: p.RequiresApproval,
}
}
// GetPeers returns a list of peers under the given account filtering out peers that do not belong to a user if // GetPeers returns a list of peers under the given account filtering out peers that do not belong to a user if
// the current user is not an admin. // the current user is not an admin.
func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, error) { func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*nbpeer.Peer, error) {
account, err := am.Store.GetAccount(accountID) account, err := am.Store.GetAccount(accountID)
if err != nil { if err != nil {
return nil, err return nil, err
@ -215,8 +50,8 @@ func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, er
return nil, err return nil, err
} }
peers := make([]*Peer, 0) peers := make([]*nbpeer.Peer, 0)
peersMap := make(map[string]*Peer) peersMap := make(map[string]*nbpeer.Peer)
for _, peer := range account.Peers { for _, peer := range account.Peers {
if !user.IsAdmin() && user.Id != peer.UserID { if !user.IsAdmin() && user.Id != peer.UserID {
// only display peers that belong to the current user if the current user is not an admin // only display peers that belong to the current user if the current user is not an admin
@ -235,7 +70,7 @@ func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, er
} }
} }
peers = make([]*Peer, 0, len(peersMap)) peers = make([]*nbpeer.Peer, 0, len(peersMap))
for _, peer := range peersMap { for _, peer := range peersMap {
peers = append(peers, peer) peers = append(peers, peer)
} }
@ -294,7 +129,7 @@ func (am *DefaultAccountManager) MarkPeerConnected(peerPubKey string, connected
} }
// UpdatePeer updates peer. Only Peer.Name, Peer.SSHEnabled, and Peer.LoginExpirationEnabled can be updated. // UpdatePeer updates peer. Only Peer.Name, Peer.SSHEnabled, and Peer.LoginExpirationEnabled can be updated.
func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Peer) (*Peer, error) { func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *nbpeer.Peer) (*nbpeer.Peer, error) {
unlock := am.Store.AcquireAccountLock(accountID) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -373,7 +208,7 @@ func (am *DefaultAccountManager) deletePeers(account *Account, peerIDs []string,
// the first loop is needed to ensure all peers present under the account before modifying, otherwise // the first loop is needed to ensure all peers present under the account before modifying, otherwise
// we might have some inconsistencies // we might have some inconsistencies
peers := make([]*Peer, 0, len(peerIDs)) peers := make([]*nbpeer.Peer, 0, len(peerIDs))
for _, peerID := range peerIDs { for _, peerID := range peerIDs {
peer := account.GetPeer(peerID) peer := account.GetPeer(peerID)
@ -465,7 +300,7 @@ func (am *DefaultAccountManager) GetPeerNetwork(peerID string) (*Network, error)
// to it. We also add the User ID to the peer metadata to identify registrant. If no userID provided, then fail with status.PermissionDenied // to it. We also add the User ID to the peer metadata to identify registrant. If no userID provided, then fail with status.PermissionDenied
// Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused). // Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused).
// The peer property is just a placeholder for the Peer properties to pass further // The peer property is just a placeholder for the Peer properties to pass further
func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*Peer, *NetworkMap, error) { func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, *NetworkMap, error) {
if setupKey == "" && userID == "" { if setupKey == "" && userID == "" {
// no auth method provided => reject access // no auth method provided => reject access
return nil, nil, status.Errorf(status.Unauthenticated, "no peer auth method provided, please use a setup key or interactive SSO login") return nil, nil, status.Errorf(status.Unauthenticated, "no peer auth method provided, please use a setup key or interactive SSO login")
@ -554,7 +389,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
return nil, nil, err return nil, nil, err
} }
newPeer := &Peer{ newPeer := &nbpeer.Peer{
ID: xid.New().String(), ID: xid.New().String(),
Key: peer.Key, Key: peer.Key,
SetupKey: upperKey, SetupKey: upperKey,
@ -563,7 +398,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
Name: peer.Meta.Hostname, Name: peer.Meta.Hostname,
DNSLabel: newLabel, DNSLabel: newLabel,
UserID: userID, UserID: userID,
Status: &PeerStatus{Connected: false, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now().UTC()},
SSHEnabled: false, SSHEnabled: false,
SSHKey: peer.SSHKey, SSHKey: peer.SSHKey,
LastLogin: time.Now().UTC(), LastLogin: time.Now().UTC(),
@ -621,7 +456,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
} }
// SyncPeer checks whether peer is eligible for receiving NetworkMap (authenticated) and returns its NetworkMap if eligible // SyncPeer checks whether peer is eligible for receiving NetworkMap (authenticated) and returns its NetworkMap if eligible
func (am *DefaultAccountManager) SyncPeer(sync PeerSync) (*Peer, *NetworkMap, error) { func (am *DefaultAccountManager) SyncPeer(sync PeerSync) (*nbpeer.Peer, *NetworkMap, error) {
account, err := am.Store.GetAccountByPeerPubKey(sync.WireGuardPubKey) account, err := am.Store.GetAccountByPeerPubKey(sync.WireGuardPubKey)
if err != nil { if err != nil {
if errStatus, ok := status.FromError(err); ok && errStatus.Type() == status.NotFound { if errStatus, ok := status.FromError(err); ok && errStatus.Type() == status.NotFound {
@ -645,7 +480,7 @@ func (am *DefaultAccountManager) SyncPeer(sync PeerSync) (*Peer, *NetworkMap, er
return nil, nil, status.Errorf(status.Unauthenticated, "peer is not registered") return nil, nil, status.Errorf(status.Unauthenticated, "peer is not registered")
} }
validatedPeers := integrations.ValidatePeers([]*Peer{peer}, account) validatedPeers := integrations.ValidatePeers([]*nbpeer.Peer{peer}, account)
if len(validatedPeers) == 0 { if len(validatedPeers) == 0 {
return nil, nil, status.Errorf(status.PermissionDenied, "peer validation failed") return nil, nil, status.Errorf(status.PermissionDenied, "peer validation failed")
} }
@ -663,14 +498,14 @@ func (am *DefaultAccountManager) SyncPeer(sync PeerSync) (*Peer, *NetworkMap, er
// LoginPeer logs in or registers a peer. // LoginPeer logs in or registers a peer.
// If peer doesn't exist the function checks whether a setup key or a user is present and registers a new peer if so. // If peer doesn't exist the function checks whether a setup key or a user is present and registers a new peer if so.
func (am *DefaultAccountManager) LoginPeer(login PeerLogin) (*Peer, *NetworkMap, error) { func (am *DefaultAccountManager) LoginPeer(login PeerLogin) (*nbpeer.Peer, *NetworkMap, error) {
account, err := am.Store.GetAccountByPeerPubKey(login.WireGuardPubKey) account, err := am.Store.GetAccountByPeerPubKey(login.WireGuardPubKey)
if err != nil { if err != nil {
if errStatus, ok := status.FromError(err); ok && errStatus.Type() == status.NotFound { if errStatus, ok := status.FromError(err); ok && errStatus.Type() == status.NotFound {
// we couldn't find this peer by its public key which can mean that peer hasn't been registered yet. // we couldn't find this peer by its public key which can mean that peer hasn't been registered yet.
// Try registering it. // Try registering it.
return am.AddPeer(login.SetupKey, login.UserID, &Peer{ return am.AddPeer(login.SetupKey, login.UserID, &nbpeer.Peer{
Key: login.WireGuardPubKey, Key: login.WireGuardPubKey,
Meta: login.Meta, Meta: login.Meta,
SSHKey: login.SSHKey, SSHKey: login.SSHKey,
@ -740,7 +575,7 @@ func (am *DefaultAccountManager) LoginPeer(login PeerLogin) (*Peer, *NetworkMap,
return peer, account.GetPeerNetworkMap(peer.ID, am.dnsDomain), nil return peer, account.GetPeerNetworkMap(peer.ID, am.dnsDomain), nil
} }
func checkIfPeerOwnerIsBlocked(peer *Peer, account *Account) error { func checkIfPeerOwnerIsBlocked(peer *nbpeer.Peer, account *Account) error {
if peer.AddedWithSSOLogin() { if peer.AddedWithSSOLogin() {
user, err := account.FindUser(peer.UserID) user, err := account.FindUser(peer.UserID)
if err != nil { if err != nil {
@ -753,7 +588,7 @@ func checkIfPeerOwnerIsBlocked(peer *Peer, account *Account) error {
return nil return nil
} }
func checkAuth(loginUserID string, peer *Peer) error { func checkAuth(loginUserID string, peer *nbpeer.Peer) error {
if loginUserID == "" { if loginUserID == "" {
// absence of a user ID indicates that JWT wasn't provided. // absence of a user ID indicates that JWT wasn't provided.
return status.Errorf(status.PermissionDenied, "peer login has expired, please log in once more") return status.Errorf(status.PermissionDenied, "peer login has expired, please log in once more")
@ -765,7 +600,7 @@ func checkAuth(loginUserID string, peer *Peer) error {
return nil return nil
} }
func peerLoginExpired(peer *Peer, account *Account) bool { func peerLoginExpired(peer *nbpeer.Peer, account *Account) bool {
expired, expiresIn := peer.LoginExpired(account.Settings.PeerLoginExpiration) expired, expiresIn := peer.LoginExpired(account.Settings.PeerLoginExpiration)
expired = account.Settings.PeerLoginExpirationEnabled && expired expired = account.Settings.PeerLoginExpirationEnabled && expired
if expired || peer.Status.LoginExpired { if expired || peer.Status.LoginExpired {
@ -775,21 +610,12 @@ func peerLoginExpired(peer *Peer, account *Account) bool {
return false return false
} }
func updatePeerLastLogin(peer *Peer, account *Account) { func updatePeerLastLogin(peer *nbpeer.Peer, account *Account) {
peer.UpdateLastLogin() peer.UpdateLastLogin()
account.UpdatePeer(peer) account.UpdatePeer(peer)
} }
// UpdateLastLogin and set login expired false func (am *DefaultAccountManager) checkAndUpdatePeerSSHKey(peer *nbpeer.Peer, account *Account, newSSHKey string) (*nbpeer.Peer, error) {
func (p *Peer) UpdateLastLogin() *Peer {
p.LastLogin = time.Now().UTC()
newStatus := p.Status.Copy()
newStatus.LoginExpired = false
p.Status = newStatus
return p
}
func (am *DefaultAccountManager) checkAndUpdatePeerSSHKey(peer *Peer, account *Account, newSSHKey string) (*Peer, error) {
if len(newSSHKey) == 0 { if len(newSSHKey) == 0 {
log.Debugf("no new SSH key provided for peer %s, skipping update", peer.ID) log.Debugf("no new SSH key provided for peer %s, skipping update", peer.ID)
return peer, nil return peer, nil
@ -860,7 +686,7 @@ func (am *DefaultAccountManager) UpdatePeerSSHKey(peerID string, sshKey string)
} }
// GetPeer for a given accountID, peerID and userID error if not found. // GetPeer for a given accountID, peerID and userID error if not found.
func (am *DefaultAccountManager) GetPeer(accountID, peerID, userID string) (*Peer, error) { func (am *DefaultAccountManager) GetPeer(accountID, peerID, userID string) (*nbpeer.Peer, error) {
unlock := am.Store.AcquireAccountLock(accountID) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -903,7 +729,7 @@ func (am *DefaultAccountManager) GetPeer(accountID, peerID, userID string) (*Pee
return nil, status.Errorf(status.Internal, "user %s has no access to peer %s under account %s", userID, peerID, accountID) return nil, status.Errorf(status.Internal, "user %s has no access to peer %s under account %s", userID, peerID, accountID)
} }
func updatePeerMeta(peer *Peer, meta PeerSystemMeta, account *Account) (*Peer, bool) { func updatePeerMeta(peer *nbpeer.Peer, meta nbpeer.PeerSystemMeta, account *Account) (*nbpeer.Peer, bool) {
if peer.UpdateMetaIfNew(meta) { if peer.UpdateMetaIfNew(meta) {
account.UpdatePeer(peer) account.UpdatePeer(peer)
return peer, true return peer, true

View File

@ -0,0 +1,181 @@
package peer
import (
"fmt"
"net"
"time"
)
// Peer represents a machine connected to the network.
// The Peer is a WireGuard peer identified by a public key
type Peer struct {
// ID is an internal ID of the peer
ID string `gorm:"primaryKey"`
// AccountID is a reference to Account that this object belongs
AccountID string `json:"-" gorm:"index;uniqueIndex:idx_peers_account_id_ip"`
// WireGuard public key
Key string `gorm:"index"`
// A setup key this peer was registered with
SetupKey string
// IP address of the Peer
IP net.IP `gorm:"uniqueIndex:idx_peers_account_id_ip"`
// Meta is a Peer system meta data
Meta PeerSystemMeta `gorm:"embedded;embeddedPrefix:meta_"`
// Name is peer's name (machine name)
Name string
// DNSLabel is the parsed peer name for domain resolution. It is used to form an FQDN by appending the account's
// domain to the peer label. e.g. peer-dns-label.netbird.cloud
DNSLabel string
// Status peer's management connection status
Status *PeerStatus `gorm:"embedded;embeddedPrefix:peer_status_"`
// The user ID that registered the peer
UserID string
// SSHKey is a public SSH key of the peer
SSHKey string
// SSHEnabled indicates whether SSH server is enabled on the peer
SSHEnabled bool
// LoginExpirationEnabled indicates whether peer's login expiration is enabled and once expired the peer has to re-login.
// Works with LastLogin
LoginExpirationEnabled bool
// LastLogin the time when peer performed last login operation
LastLogin time.Time
// Indicate ephemeral peer attribute
Ephemeral bool
}
type PeerStatus struct {
// LastSeen is the last time peer was connected to the management service
LastSeen time.Time
// Connected indicates whether peer is connected to the management service or not
Connected bool
// LoginExpired
LoginExpired bool
// RequiresApproval indicates whether peer requires approval or not
RequiresApproval bool
}
// PeerSystemMeta is a metadata of a Peer machine system
type PeerSystemMeta struct {
Hostname string
GoOS string
Kernel string
Core string
Platform string
OS string
WtVersion string
UIVersion string
}
func (p PeerSystemMeta) isEqual(other PeerSystemMeta) bool {
return p.Hostname == other.Hostname &&
p.GoOS == other.GoOS &&
p.Kernel == other.Kernel &&
p.Core == other.Core &&
p.Platform == other.Platform &&
p.OS == other.OS &&
p.WtVersion == other.WtVersion &&
p.UIVersion == other.UIVersion
}
// AddedWithSSOLogin indicates whether this peer has been added with an SSO login by a user.
func (p *Peer) AddedWithSSOLogin() bool {
return p.UserID != ""
}
// Copy copies Peer object
func (p *Peer) Copy() *Peer {
peerStatus := p.Status
if peerStatus != nil {
peerStatus = p.Status.Copy()
}
return &Peer{
ID: p.ID,
AccountID: p.AccountID,
Key: p.Key,
SetupKey: p.SetupKey,
IP: p.IP,
Meta: p.Meta,
Name: p.Name,
DNSLabel: p.DNSLabel,
Status: peerStatus,
UserID: p.UserID,
SSHKey: p.SSHKey,
SSHEnabled: p.SSHEnabled,
LoginExpirationEnabled: p.LoginExpirationEnabled,
LastLogin: p.LastLogin,
Ephemeral: p.Ephemeral,
}
}
// UpdateMetaIfNew updates peer's system metadata if new information is provided
// returns true if meta was updated, false otherwise
func (p *Peer) UpdateMetaIfNew(meta PeerSystemMeta) bool {
// Avoid overwriting UIVersion if the update was triggered sole by the CLI client
if meta.UIVersion == "" {
meta.UIVersion = p.Meta.UIVersion
}
if p.Meta.isEqual(meta) {
return false
}
p.Meta = meta
return true
}
// MarkLoginExpired marks peer's status expired or not
func (p *Peer) MarkLoginExpired(expired bool) {
newStatus := p.Status.Copy()
newStatus.LoginExpired = expired
if expired {
newStatus.Connected = false
}
p.Status = newStatus
}
// LoginExpired indicates whether the peer's login has expired or not.
// If Peer.LastLogin plus the expiresIn duration has happened already; then login has expired.
// Return true if a login has expired, false otherwise, and time left to expiration (negative when expired).
// Login expiration can be disabled/enabled on a Peer level via Peer.LoginExpirationEnabled property.
// Login expiration can also be disabled/enabled globally on the Account level via Settings.PeerLoginExpirationEnabled.
// Only peers added by interactive SSO login can be expired.
func (p *Peer) LoginExpired(expiresIn time.Duration) (bool, time.Duration) {
if !p.AddedWithSSOLogin() || !p.LoginExpirationEnabled {
return false, 0
}
expiresAt := p.LastLogin.Add(expiresIn)
now := time.Now()
timeLeft := expiresAt.Sub(now)
return timeLeft <= 0, timeLeft
}
// FQDN returns peers FQDN combined of the peer's DNS label and the system's DNS domain
func (p *Peer) FQDN(dnsDomain string) string {
if dnsDomain == "" {
return ""
}
return fmt.Sprintf("%s.%s", p.DNSLabel, dnsDomain)
}
// EventMeta returns activity event meta related to the peer
func (p *Peer) EventMeta(dnsDomain string) map[string]any {
return map[string]any{"name": p.Name, "fqdn": p.FQDN(dnsDomain), "ip": p.IP}
}
// Copy PeerStatus
func (p *PeerStatus) Copy() *PeerStatus {
return &PeerStatus{
LastSeen: p.LastSeen,
Connected: p.Connected,
LoginExpired: p.LoginExpired,
RequiresApproval: p.RequiresApproval,
}
}
// UpdateLastLogin and set login expired false
func (p *Peer) UpdateLastLogin() *Peer {
p.LastLogin = time.Now().UTC()
newStatus := p.Status.Copy()
newStatus.LoginExpired = false
p.Status = newStatus
return p
}

View File

@ -8,6 +8,8 @@ import (
"github.com/rs/xid" "github.com/rs/xid"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
) )
func TestPeer_LoginExpired(t *testing.T) { func TestPeer_LoginExpired(t *testing.T) {
@ -52,7 +54,7 @@ func TestPeer_LoginExpired(t *testing.T) {
for _, c := range tt { for _, c := range tt {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
peer := &Peer{ peer := &nbpeer.Peer{
LoginExpirationEnabled: c.expirationEnabled, LoginExpirationEnabled: c.expirationEnabled,
LastLogin: c.lastLogin, LastLogin: c.lastLogin,
UserID: userID, UserID: userID,
@ -90,9 +92,9 @@ func TestAccountManager_GetNetworkMap(t *testing.T) {
return return
} }
peer1, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer1, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey1.PublicKey().String(), Key: peerKey1.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-1"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -104,9 +106,9 @@ func TestAccountManager_GetNetworkMap(t *testing.T) {
t.Fatal(err) t.Fatal(err)
return return
} }
_, _, err = manager.AddPeer(setupKey.Key, "", &Peer{ _, _, err = manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey2.PublicKey().String(), Key: peerKey2.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-2"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
}) })
if err != nil { if err != nil {
@ -163,9 +165,9 @@ func TestAccountManager_GetNetworkMapWithPolicy(t *testing.T) {
return return
} }
peer1, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer1, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey1.PublicKey().String(), Key: peerKey1.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-1"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -177,9 +179,9 @@ func TestAccountManager_GetNetworkMapWithPolicy(t *testing.T) {
t.Fatal(err) t.Fatal(err)
return return
} }
peer2, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer2, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey2.PublicKey().String(), Key: peerKey2.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-2"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -339,9 +341,9 @@ func TestAccountManager_GetPeerNetwork(t *testing.T) {
return return
} }
peer1, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer1, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey1.PublicKey().String(), Key: peerKey1.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-1"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-1"},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -353,9 +355,9 @@ func TestAccountManager_GetPeerNetwork(t *testing.T) {
t.Fatal(err) t.Fatal(err)
return return
} }
_, _, err = manager.AddPeer(setupKey.Key, "", &Peer{ _, _, err = manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey2.PublicKey().String(), Key: peerKey2.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-2"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
}) })
if err != nil { if err != nil {
@ -409,9 +411,9 @@ func TestDefaultAccountManager_GetPeer(t *testing.T) {
return return
} }
peer1, _, err := manager.AddPeer("", someUser, &Peer{ peer1, _, err := manager.AddPeer("", someUser, &nbpeer.Peer{
Key: peerKey1.PublicKey().String(), Key: peerKey1.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-2"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
}) })
if err != nil { if err != nil {
t.Errorf("expecting peer to be added, got failure %v", err) t.Errorf("expecting peer to be added, got failure %v", err)
@ -425,9 +427,9 @@ func TestDefaultAccountManager_GetPeer(t *testing.T) {
} }
// the second peer added with a setup key // the second peer added with a setup key
peer2, _, err := manager.AddPeer(setupKey.Key, "", &Peer{ peer2, _, err := manager.AddPeer(setupKey.Key, "", &nbpeer.Peer{
Key: peerKey2.PublicKey().String(), Key: peerKey2.PublicKey().String(),
Meta: PeerSystemMeta{Hostname: "test-peer-2"}, Meta: nbpeer.PeerSystemMeta{Hostname: "test-peer-2"},
}) })
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -9,6 +9,7 @@ import (
"github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
) )
@ -205,7 +206,7 @@ type FirewallRule struct {
// getPeerConnectionResources for a given peer // getPeerConnectionResources for a given peer
// //
// This function returns the list of peers and firewall rules that are applicable to a given peer. // This function returns the list of peers and firewall rules that are applicable to a given peer.
func (a *Account) getPeerConnectionResources(peerID string) ([]*Peer, []*FirewallRule) { func (a *Account) getPeerConnectionResources(peerID string) ([]*nbpeer.Peer, []*FirewallRule) {
generateResources, getAccumulatedResources := a.connResourcesGenerator() generateResources, getAccumulatedResources := a.connResourcesGenerator()
for _, policy := range a.Policies { for _, policy := range a.Policies {
if !policy.Enabled { if !policy.Enabled {
@ -247,11 +248,11 @@ func (a *Account) getPeerConnectionResources(peerID string) ([]*Peer, []*Firewal
// The generator function is used to generate the list of peers and firewall rules that are applicable to a given peer. // The generator function is used to generate the list of peers and firewall rules that are applicable to a given peer.
// It safe to call the generator function multiple times for same peer and different rules no duplicates will be // It safe to call the generator function multiple times for same peer and different rules no duplicates will be
// generated. The accumulator function returns the result of all the generator calls. // generated. The accumulator function returns the result of all the generator calls.
func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*Peer, int), func() ([]*Peer, []*FirewallRule)) { func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*nbpeer.Peer, int), func() ([]*nbpeer.Peer, []*FirewallRule)) {
rulesExists := make(map[string]struct{}) rulesExists := make(map[string]struct{})
peersExists := make(map[string]struct{}) peersExists := make(map[string]struct{})
rules := make([]*FirewallRule, 0) rules := make([]*FirewallRule, 0)
peers := make([]*Peer, 0) peers := make([]*nbpeer.Peer, 0)
all, err := a.GetGroupAll() all, err := a.GetGroupAll()
if err != nil { if err != nil {
@ -259,7 +260,7 @@ func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*Peer, int), fun
all = &Group{} all = &Group{}
} }
return func(rule *PolicyRule, groupPeers []*Peer, direction int) { return func(rule *PolicyRule, groupPeers []*nbpeer.Peer, direction int) {
isAll := (len(all.Peers) - 1) == len(groupPeers) isAll := (len(all.Peers) - 1) == len(groupPeers)
for _, peer := range groupPeers { for _, peer := range groupPeers {
if peer == nil { if peer == nil {
@ -299,7 +300,7 @@ func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*Peer, int), fun
rules = append(rules, &pr) rules = append(rules, &pr)
} }
} }
}, func() ([]*Peer, []*FirewallRule) { }, func() ([]*nbpeer.Peer, []*FirewallRule) {
return peers, rules return peers, rules
} }
} }
@ -478,9 +479,9 @@ func toProtocolFirewallRules(update []*FirewallRule) []*proto.FirewallRule {
// getAllPeersFromGroups for given peer ID and list of groups // getAllPeersFromGroups for given peer ID and list of groups
// //
// Returns list of peers and boolean indicating if peer is in any of the groups // Returns list of peers and boolean indicating if peer is in any of the groups
func getAllPeersFromGroups(account *Account, groups []string, peerID string) ([]*Peer, bool) { func getAllPeersFromGroups(account *Account, groups []string, peerID string) ([]*nbpeer.Peer, bool) {
peerInGroups := false peerInGroups := false
filteredPeers := make([]*Peer, 0, len(groups)) filteredPeers := make([]*nbpeer.Peer, 0, len(groups))
for _, g := range groups { for _, g := range groups {
group, ok := account.Groups[g] group, ok := account.Groups[g]
if !ok { if !ok {

View File

@ -7,11 +7,13 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
) )
func TestAccount_getPeersByPolicy(t *testing.T) { func TestAccount_getPeersByPolicy(t *testing.T) {
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peerA": { "peerA": {
ID: "peerA", ID: "peerA",
IP: net.ParseIP("100.65.14.88"), IP: net.ParseIP("100.65.14.88"),
@ -255,7 +257,7 @@ func TestAccount_getPeersByPolicy(t *testing.T) {
func TestAccount_getPeersByPolicyDirect(t *testing.T) { func TestAccount_getPeersByPolicyDirect(t *testing.T) {
account := &Account{ account := &Account{
Peers: map[string]*Peer{ Peers: map[string]*nbpeer.Peer{
"peerA": { "peerA": {
ID: "peerA", ID: "peerA",
IP: net.ParseIP("100.65.14.88"), IP: net.ParseIP("100.65.14.88"),

View File

@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/route" "github.com/netbirdio/netbird/route"
) )
@ -1045,13 +1046,13 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
return nil, err return nil, err
} }
peer1 := &Peer{ peer1 := &nbpeer.Peer{
IP: peer1IP, IP: peer1IP,
ID: peer1ID, ID: peer1ID,
Key: peer1Key, Key: peer1Key,
Name: "test-host1@netbird.io", Name: "test-host1@netbird.io",
UserID: userID, UserID: userID,
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host1@netbird.io", Hostname: "test-host1@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -1070,13 +1071,13 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
return nil, err return nil, err
} }
peer2 := &Peer{ peer2 := &nbpeer.Peer{
IP: peer2IP, IP: peer2IP,
ID: peer2ID, ID: peer2ID,
Key: peer2Key, Key: peer2Key,
Name: "test-host2@netbird.io", Name: "test-host2@netbird.io",
UserID: userID, UserID: userID,
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host2@netbird.io", Hostname: "test-host2@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -1095,13 +1096,13 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
return nil, err return nil, err
} }
peer3 := &Peer{ peer3 := &nbpeer.Peer{
IP: peer3IP, IP: peer3IP,
ID: peer3ID, ID: peer3ID,
Key: peer3Key, Key: peer3Key,
Name: "test-host3@netbird.io", Name: "test-host3@netbird.io",
UserID: userID, UserID: userID,
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host3@netbird.io", Hostname: "test-host3@netbird.io",
GoOS: "darwin", GoOS: "darwin",
Kernel: "Darwin", Kernel: "Darwin",
@ -1120,13 +1121,13 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
return nil, err return nil, err
} }
peer4 := &Peer{ peer4 := &nbpeer.Peer{
IP: peer4IP, IP: peer4IP,
ID: peer4ID, ID: peer4ID,
Key: peer4Key, Key: peer4Key,
Name: "test-host4@netbird.io", Name: "test-host4@netbird.io",
UserID: userID, UserID: userID,
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host4@netbird.io", Hostname: "test-host4@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",
@ -1145,13 +1146,13 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
return nil, err return nil, err
} }
peer5 := &Peer{ peer5 := &nbpeer.Peer{
IP: peer5IP, IP: peer5IP,
ID: peer5ID, ID: peer5ID,
Key: peer5Key, Key: peer5Key,
Name: "test-host4@netbird.io", Name: "test-host4@netbird.io",
UserID: userID, UserID: userID,
Meta: PeerSystemMeta{ Meta: nbpeer.PeerSystemMeta{
Hostname: "test-host4@netbird.io", Hostname: "test-host4@netbird.io",
GoOS: "linux", GoOS: "linux",
Kernel: "Linux", Kernel: "Linux",

View File

@ -7,15 +7,17 @@ import (
"sync" "sync"
"time" "time"
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/route"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
nbdns "github.com/netbirdio/netbird/dns"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/route"
) )
// SqliteStore represents an account storage backed by a Sqlite DB persisted to disk // SqliteStore represents an account storage backed by a Sqlite DB persisted to disk
@ -58,7 +60,7 @@ func NewSqliteStore(dataDir string, metrics telemetry.AppMetrics) (*SqliteStore,
sql.SetMaxOpenConns(conns) // TODO: make it configurable sql.SetMaxOpenConns(conns) // TODO: make it configurable
err = db.AutoMigrate( err = db.AutoMigrate(
&SetupKey{}, &Peer{}, &User{}, &PersonalAccessToken{}, &Group{}, &Rule{}, &SetupKey{}, &nbpeer.Peer{}, &User{}, &PersonalAccessToken{}, &Group{}, &Rule{},
&Account{}, &Policy{}, &PolicyRule{}, &route.Route{}, &nbdns.NameServerGroup{}, &Account{}, &Policy{}, &PolicyRule{}, &route.Route{}, &nbdns.NameServerGroup{},
&installation{}, &installation{},
) )
@ -219,8 +221,8 @@ func (s *SqliteStore) GetInstallationID() string {
return installation.InstallationIDValue return installation.InstallationIDValue
} }
func (s *SqliteStore) SavePeerStatus(accountID, peerID string, peerStatus PeerStatus) error { func (s *SqliteStore) SavePeerStatus(accountID, peerID string, peerStatus nbpeer.PeerStatus) error {
var peer Peer var peer nbpeer.Peer
result := s.db.First(&peer, "account_id = ? and id = ?", accountID, peerID) result := s.db.First(&peer, "account_id = ? and id = ?", accountID, peerID)
if result.Error != nil { if result.Error != nil {
@ -347,7 +349,7 @@ func (s *SqliteStore) GetAccount(accountID string) (*Account, error) {
} }
account.SetupKeysG = nil account.SetupKeysG = nil
account.Peers = make(map[string]*Peer, len(account.PeersG)) account.Peers = make(map[string]*nbpeer.Peer, len(account.PeersG))
for _, peer := range account.PeersG { for _, peer := range account.PeersG {
account.Peers[peer.ID] = peer.Copy() account.Peers[peer.ID] = peer.Copy()
} }
@ -405,7 +407,7 @@ func (s *SqliteStore) GetAccountByUser(userID string) (*Account, error) {
} }
func (s *SqliteStore) GetAccountByPeerID(peerID string) (*Account, error) { func (s *SqliteStore) GetAccountByPeerID(peerID string) (*Account, error) {
var peer Peer var peer nbpeer.Peer
result := s.db.Select("account_id").First(&peer, "id = ?", peerID) result := s.db.Select("account_id").First(&peer, "id = ?", peerID)
if result.Error != nil { if result.Error != nil {
return nil, status.Errorf(status.NotFound, "account not found: index lookup failed") return nil, status.Errorf(status.NotFound, "account not found: index lookup failed")
@ -419,7 +421,7 @@ func (s *SqliteStore) GetAccountByPeerID(peerID string) (*Account, error) {
} }
func (s *SqliteStore) GetAccountByPeerPubKey(peerKey string) (*Account, error) { func (s *SqliteStore) GetAccountByPeerPubKey(peerKey string) (*Account, error) {
var peer Peer var peer nbpeer.Peer
result := s.db.Select("account_id").First(&peer, "key = ?", peerKey) result := s.db.Select("account_id").First(&peer, "key = ?", peerKey)
if result.Error != nil { if result.Error != nil {

View File

@ -9,9 +9,11 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/netbirdio/netbird/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/util"
) )
func TestSqlite_NewStore(t *testing.T) { func TestSqlite_NewStore(t *testing.T) {
@ -36,13 +38,13 @@ func TestSqlite_SaveAccount(t *testing.T) {
account := newAccountWithId("account_id", "testuser", "") account := newAccountWithId("account_id", "testuser", "")
setupKey := GenerateDefaultSetupKey() setupKey := GenerateDefaultSetupKey()
account.SetupKeys[setupKey.Key] = setupKey account.SetupKeys[setupKey.Key] = setupKey
account.Peers["testpeer"] = &Peer{ account.Peers["testpeer"] = &nbpeer.Peer{
Key: "peerkey", Key: "peerkey",
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: true, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
} }
err := store.SaveAccount(account) err := store.SaveAccount(account)
@ -51,13 +53,13 @@ func TestSqlite_SaveAccount(t *testing.T) {
account2 := newAccountWithId("account_id2", "testuser2", "") account2 := newAccountWithId("account_id2", "testuser2", "")
setupKey = GenerateDefaultSetupKey() setupKey = GenerateDefaultSetupKey()
account2.SetupKeys[setupKey.Key] = setupKey account2.SetupKeys[setupKey.Key] = setupKey
account2.Peers["testpeer2"] = &Peer{ account2.Peers["testpeer2"] = &nbpeer.Peer{
Key: "peerkey2", Key: "peerkey2",
SetupKey: "peerkeysetupkey2", SetupKey: "peerkeysetupkey2",
IP: net.IP{127, 0, 0, 2}, IP: net.IP{127, 0, 0, 2},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name 2", Name: "peer name 2",
Status: &PeerStatus{Connected: true, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
} }
err = store.SaveAccount(account2) err = store.SaveAccount(account2)
@ -109,19 +111,19 @@ func TestSqlite_SavePeerStatus(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// save status of non-existing peer // save status of non-existing peer
newStatus := PeerStatus{Connected: true, LastSeen: time.Now().UTC()} newStatus := nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()}
err = store.SavePeerStatus(account.Id, "non-existing-peer", newStatus) err = store.SavePeerStatus(account.Id, "non-existing-peer", newStatus)
assert.Error(t, err) assert.Error(t, err)
// save new status of existing peer // save new status of existing peer
account.Peers["testpeer"] = &Peer{ account.Peers["testpeer"] = &nbpeer.Peer{
Key: "peerkey", Key: "peerkey",
ID: "testpeer", ID: "testpeer",
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: false, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now().UTC()},
} }
err = store.SaveAccount(account) err = store.SaveAccount(account)
@ -216,13 +218,13 @@ func newAccount(store Store, id int) error {
account := newAccountWithId(str, str+"-testuser", "example.com") account := newAccountWithId(str, str+"-testuser", "example.com")
setupKey := GenerateDefaultSetupKey() setupKey := GenerateDefaultSetupKey()
account.SetupKeys[setupKey.Key] = setupKey account.SetupKeys[setupKey.Key] = setupKey
account.Peers["p"+str] = &Peer{ account.Peers["p"+str] = &nbpeer.Peer{
Key: "peerkey" + str, Key: "peerkey" + str,
SetupKey: "peerkeysetupkey", SetupKey: "peerkeysetupkey",
IP: net.IP{127, 0, 0, 1}, IP: net.IP{127, 0, 0, 1},
Meta: PeerSystemMeta{}, Meta: nbpeer.PeerSystemMeta{},
Name: "peer name", Name: "peer name",
Status: &PeerStatus{Connected: true, LastSeen: time.Now().UTC()}, Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
} }
return store.SaveAccount(account) return store.SaveAccount(account)

View File

@ -8,6 +8,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/telemetry" "github.com/netbirdio/netbird/management/server/telemetry"
) )
@ -30,7 +31,7 @@ type Store interface {
AcquireAccountLock(accountID string) func() AcquireAccountLock(accountID string) func()
// AcquireGlobalLock should attempt to acquire a global lock and return a function that releases the lock // AcquireGlobalLock should attempt to acquire a global lock and return a function that releases the lock
AcquireGlobalLock() func() AcquireGlobalLock() func()
SavePeerStatus(accountID, peerID string, status PeerStatus) error SavePeerStatus(accountID, peerID string, status nbpeer.PeerStatus) error
SaveUserLastLogin(accountID, userID string, lastLogin time.Time) error SaveUserLastLogin(accountID, userID string, lastLogin time.Time) error
// Close should close the store persisting all unsaved data. // Close should close the store persisting all unsaved data.
Close() error Close() error

View File

@ -11,6 +11,7 @@ import (
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/idp" "github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
) )
@ -980,7 +981,7 @@ func (am *DefaultAccountManager) GetUsersFromAccount(accountID, userID string) (
} }
// expireAndUpdatePeers expires all peers of the given user and updates them in the account // expireAndUpdatePeers expires all peers of the given user and updates them in the account
func (am *DefaultAccountManager) expireAndUpdatePeers(account *Account, peers []*Peer) error { func (am *DefaultAccountManager) expireAndUpdatePeers(account *Account, peers []*nbpeer.Peer) error {
var peerIDs []string var peerIDs []string
for _, peer := range peers { for _, peer := range peers {
if peer.Status.LoginExpired { if peer.Status.LoginExpired {