mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-21 23:53:14 +01:00
Use Peer.ID instead of Peer.Key as peer identifier (#664)
Replace Peer.Key as internal identifier with a randomly generated Peer.ID in the Management service. Every group now references peers by ID instead of a public key. Every route now references peers by ID instead of a public key. FileStore does store.json file migration on startup by generating Peer.ID and replacing all Peer.Key identifier references .
This commit is contained in:
parent
9e408b5bbc
commit
9adadfade4
@ -50,24 +50,24 @@ type AccountManager interface {
|
||||
GetAccountFromToken(claims jwtclaims.AuthorizationClaims) (*Account, *User, error)
|
||||
IsUserAdmin(claims jwtclaims.AuthorizationClaims) (bool, error)
|
||||
AccountExists(accountId string) (*bool, error)
|
||||
GetPeer(peerKey string) (*Peer, error)
|
||||
GetPeerByKey(peerKey string) (*Peer, error)
|
||||
GetPeers(accountID, userID string) ([]*Peer, error)
|
||||
MarkPeerConnected(peerKey string, connected bool) error
|
||||
DeletePeer(accountID, peerKey, userID string) (*Peer, error)
|
||||
DeletePeer(accountID, peerID, userID string) (*Peer, error)
|
||||
GetPeerByIP(accountId string, peerIP string) (*Peer, error)
|
||||
UpdatePeer(accountID, userID string, peer *Peer) (*Peer, error)
|
||||
GetNetworkMap(peerKey string) (*NetworkMap, error)
|
||||
GetPeerNetwork(peerKey string) (*Network, error)
|
||||
GetNetworkMap(peerID string) (*NetworkMap, error)
|
||||
GetPeerNetwork(peerID string) (*Network, error)
|
||||
AddPeer(setupKey, userID string, peer *Peer) (*Peer, error)
|
||||
UpdatePeerMeta(peerKey string, meta PeerSystemMeta) error
|
||||
UpdatePeerSSHKey(peerKey string, sshKey string) error
|
||||
UpdatePeerMeta(peerID string, meta PeerSystemMeta) error
|
||||
UpdatePeerSSHKey(peerID string, sshKey string) error
|
||||
GetUsersFromAccount(accountID, userID string) ([]*UserInfo, error)
|
||||
GetGroup(accountId, groupID string) (*Group, error)
|
||||
SaveGroup(accountID, userID string, group *Group) error
|
||||
UpdateGroup(accountID string, groupID string, operations []GroupUpdateOperation) (*Group, error)
|
||||
DeleteGroup(accountId, groupID string) error
|
||||
ListGroups(accountId string) ([]*Group, error)
|
||||
GroupAddPeer(accountId, groupID, peerKey string) error
|
||||
GroupAddPeer(accountId, groupID, peerID string) error
|
||||
GroupDeletePeer(accountId, groupID, peerKey string) error
|
||||
GroupListPeers(accountId, groupID string) ([]*Peer, error)
|
||||
GetRule(accountID, ruleID, userID string) (*Rule, error)
|
||||
@ -76,7 +76,7 @@ type AccountManager interface {
|
||||
DeleteRule(accountID, ruleID, userID string) error
|
||||
ListRules(accountID, userID string) ([]*Rule, error)
|
||||
GetRoute(accountID, routeID, userID string) (*route.Route, error)
|
||||
CreateRoute(accountID string, prefix, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
|
||||
CreateRoute(accountID string, prefix, peerID, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
|
||||
SaveRoute(accountID, userID string, route *route.Route) error
|
||||
UpdateRoute(accountID, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
|
||||
DeleteRoute(accountID, routeID, userID string) error
|
||||
@ -144,7 +144,8 @@ type UserInfo struct {
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (a *Account) getRoutesToSync(peerID string, aclPeers []*Peer) []*route.Route {
|
||||
routes, peerDisabledRoutes := a.getEnabledAndDisabledRoutesByPeer(peerID)
|
||||
peerRoutesMembership := make(lookupMap)
|
||||
@ -154,7 +155,7 @@ func (a *Account) getRoutesToSync(peerID string, aclPeers []*Peer) []*route.Rout
|
||||
|
||||
groupListMap := a.getPeerGroups(peerID)
|
||||
for _, peer := range aclPeers {
|
||||
activeRoutes, _ := a.getEnabledAndDisabledRoutesByPeer(peer.Key)
|
||||
activeRoutes, _ := a.getEnabledAndDisabledRoutesByPeer(peer.ID)
|
||||
groupFilteredRoutes := a.filterRoutesByGroups(activeRoutes, groupListMap)
|
||||
filteredRoutes := a.filterRoutesFromPeersOfSameHAGroup(groupFilteredRoutes, peerRoutesMembership)
|
||||
routes = append(routes, filteredRoutes...)
|
||||
@ -190,18 +191,27 @@ func (a *Account) filterRoutesByGroups(routes []*route.Route, groupListMap looku
|
||||
return filteredRoutes
|
||||
}
|
||||
|
||||
// getEnabledAndDisabledRoutesByPeer returns the enabled and disabled lists of routes that belong to a peer
|
||||
func (a *Account) getEnabledAndDisabledRoutesByPeer(peerPubKey string) ([]*route.Route, []*route.Route) {
|
||||
//TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
||||
// getEnabledAndDisabledRoutesByPeer returns the enabled and disabled lists of routes that belong to a peer.
|
||||
// Please mind, that the returned route.Route objects will contain Peer.Key instead of Peer.ID.
|
||||
func (a *Account) getEnabledAndDisabledRoutesByPeer(peerID string) ([]*route.Route, []*route.Route) {
|
||||
var enabledRoutes []*route.Route
|
||||
var disabledRoutes []*route.Route
|
||||
for _, r := range a.Routes {
|
||||
if r.Peer == peerPubKey {
|
||||
if r.Enabled {
|
||||
enabledRoutes = append(enabledRoutes, r)
|
||||
if r.Peer == peerID {
|
||||
// We need to set Peer.Key instead of Peer.ID because this object will be sent to agents as part of a network map.
|
||||
// Ideally we should have a separate field for that, but fine for now.
|
||||
peer := a.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
log.Errorf("route %s has peer %s that doesn't exist under account %s", r.ID, peerID, a.Id)
|
||||
continue
|
||||
}
|
||||
disabledRoutes = append(disabledRoutes, r)
|
||||
raut := r.Copy()
|
||||
raut.Peer = peer.Key
|
||||
if r.Enabled {
|
||||
enabledRoutes = append(enabledRoutes, raut)
|
||||
continue
|
||||
}
|
||||
disabledRoutes = append(disabledRoutes, raut)
|
||||
}
|
||||
}
|
||||
return enabledRoutes, disabledRoutes
|
||||
@ -232,7 +242,7 @@ func (a *Account) GetPeerByIP(peerIP string) *Peer {
|
||||
}
|
||||
|
||||
// GetPeerRules returns a list of source or destination rules of a given peer.
|
||||
func (a *Account) GetPeerRules(peerPubKey string) (srcRules []*Rule, dstRules []*Rule) {
|
||||
func (a *Account) GetPeerRules(peerID string) (srcRules []*Rule, dstRules []*Rule) {
|
||||
|
||||
// Rules are group based so there is no direct access to peers.
|
||||
// First, find all groups that the given peer belongs to
|
||||
@ -240,7 +250,7 @@ func (a *Account) GetPeerRules(peerPubKey string) (srcRules []*Rule, dstRules []
|
||||
|
||||
for s, group := range a.Groups {
|
||||
for _, peer := range group.Peers {
|
||||
if peerPubKey == peer {
|
||||
if peerID == peer {
|
||||
peerGroups[s] = struct{}{}
|
||||
break
|
||||
}
|
||||
@ -284,18 +294,15 @@ func (a *Account) GetPeers() []*Peer {
|
||||
|
||||
// UpdatePeer saves new or replaces existing peer
|
||||
func (a *Account) UpdatePeer(update *Peer) {
|
||||
//TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
||||
a.Peers[update.Key] = update
|
||||
a.Peers[update.ID] = update
|
||||
}
|
||||
|
||||
// DeletePeer deletes peer from the account cleaning up all the references
|
||||
func (a *Account) DeletePeer(peerPubKey string) {
|
||||
// TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
||||
|
||||
func (a *Account) DeletePeer(peerID string) {
|
||||
// delete peer from groups
|
||||
for _, g := range a.Groups {
|
||||
for i, pk := range g.Peers {
|
||||
if pk == peerPubKey {
|
||||
if pk == peerID {
|
||||
g.Peers = append(g.Peers[:i], g.Peers[i+1:]...)
|
||||
break
|
||||
}
|
||||
@ -303,13 +310,13 @@ func (a *Account) DeletePeer(peerPubKey string) {
|
||||
}
|
||||
|
||||
for _, r := range a.Routes {
|
||||
if r.Peer == peerPubKey {
|
||||
if r.Peer == peerID {
|
||||
r.Enabled = false
|
||||
r.Peer = ""
|
||||
}
|
||||
}
|
||||
|
||||
delete(a.Peers, peerPubKey)
|
||||
delete(a.Peers, peerID)
|
||||
a.Network.IncSerial()
|
||||
}
|
||||
|
||||
@ -476,6 +483,11 @@ func (a *Account) GetGroupAll() (*Group, error) {
|
||||
return nil, fmt.Errorf("no group ALL found")
|
||||
}
|
||||
|
||||
// GetPeer looks up a Peer by ID
|
||||
func (a *Account) GetPeer(peerID string) *Peer {
|
||||
return a.Peers[peerID]
|
||||
}
|
||||
|
||||
// BuildManager creates a new DefaultAccountManager with a provided Store
|
||||
func BuildManager(store Store, peersUpdateManager *PeersUpdateManager, idpManager idp.Manager,
|
||||
singleAccountModeDomain string, dnsDomain string, eventStore activity.Store) (*DefaultAccountManager, error) {
|
||||
@ -1015,7 +1027,7 @@ func addAllGroup(account *Account) {
|
||||
Name: "All",
|
||||
}
|
||||
for _, peer := range account.Peers {
|
||||
allGroup.Peers = append(allGroup.Peers, peer.Key)
|
||||
allGroup.Peers = append(allGroup.Peers, peer.ID)
|
||||
}
|
||||
account.Groups = map[string]*Group{allGroup.ID: allGroup}
|
||||
|
||||
|
@ -493,8 +493,8 @@ func TestAccountManager_GetAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, peer := range account.Peers {
|
||||
if _, ok := getAccount.Peers[peer.Key]; !ok {
|
||||
t.Errorf("expected account to have peer %s, not found", peer.Key)
|
||||
if _, ok := getAccount.Peers[peer.ID]; !ok {
|
||||
t.Errorf("expected account to have peer %s, not found", peer.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -580,7 +580,7 @@ func TestAccountManager_AddPeer(t *testing.T) {
|
||||
assert.Equal(t, peer.Name, ev.Meta["name"])
|
||||
assert.Equal(t, peer.FQDN(account.Domain), ev.Meta["fqdn"])
|
||||
assert.Equal(t, setupKey.Id, ev.InitiatorID)
|
||||
assert.Equal(t, peer.IP.String(), ev.TargetID)
|
||||
assert.Equal(t, peer.ID, ev.TargetID)
|
||||
assert.Equal(t, peer.IP.String(), fmt.Sprint(ev.Meta["ip"]))
|
||||
}
|
||||
|
||||
@ -650,7 +650,7 @@ func TestAccountManager_AddPeerWithUserID(t *testing.T) {
|
||||
assert.Equal(t, peer.Name, ev.Meta["name"])
|
||||
assert.Equal(t, peer.FQDN(account.Domain), ev.Meta["fqdn"])
|
||||
assert.Equal(t, userID, ev.InitiatorID)
|
||||
assert.Equal(t, peer.IP.String(), ev.TargetID)
|
||||
assert.Equal(t, peer.ID, ev.TargetID)
|
||||
assert.Equal(t, peer.IP.String(), fmt.Sprint(ev.Meta["ip"]))
|
||||
}
|
||||
|
||||
@ -717,13 +717,13 @@ func TestAccountManager_NetworkUpdates(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
updMsg := manager.peersUpdateManager.CreateChannel(peer1.Key)
|
||||
defer manager.peersUpdateManager.CloseChannel(peer1.Key)
|
||||
updMsg := manager.peersUpdateManager.CreateChannel(peer1.ID)
|
||||
defer manager.peersUpdateManager.CloseChannel(peer1.ID)
|
||||
|
||||
group := Group{
|
||||
ID: "group-id",
|
||||
Name: "GroupA",
|
||||
Peers: []string{peer1.Key, peer2.Key, peer3.Key},
|
||||
Peers: []string{peer1.ID, peer2.ID, peer3.ID},
|
||||
}
|
||||
|
||||
rule := Rule{
|
||||
@ -810,7 +810,7 @@ func TestAccountManager_NetworkUpdates(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err := manager.DeletePeer(account.Id, peer3.Key, userID); err != nil {
|
||||
if _, err := manager.DeletePeer(account.Id, peer3.ID, userID); err != nil {
|
||||
t.Errorf("delete peer: %v", err)
|
||||
return
|
||||
}
|
||||
@ -1001,13 +1001,13 @@ func TestAccountManager_UpdatePeerMeta(t *testing.T) {
|
||||
OS: "new-OS",
|
||||
WtVersion: "new-WtVersion",
|
||||
}
|
||||
err = manager.UpdatePeerMeta(peer.Key, newMeta)
|
||||
err = manager.UpdatePeerMeta(peer.ID, newMeta)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
p, err := manager.GetPeer(peer.Key)
|
||||
p, err := manager.GetPeerByKey(peer.Key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -147,7 +147,17 @@ func TestGetNetworkMap_DNSConfigSync(t *testing.T) {
|
||||
t.Error("failed to init testing account")
|
||||
}
|
||||
|
||||
newAccountDNSConfig, err := am.GetNetworkMap(dnsPeer1Key)
|
||||
peer1, err := account.FindPeerByPubKey(dnsPeer1Key)
|
||||
if err != nil {
|
||||
t.Error("failed to init testing account")
|
||||
}
|
||||
|
||||
peer2, err := account.FindPeerByPubKey(dnsPeer2Key)
|
||||
if err != nil {
|
||||
t.Error("failed to init testing account")
|
||||
}
|
||||
|
||||
newAccountDNSConfig, err := am.GetNetworkMap(peer1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, newAccountDNSConfig.DNSConfig.CustomZones, 1, "default DNS config should have one custom zone for peers")
|
||||
require.True(t, newAccountDNSConfig.DNSConfig.ServiceEnable, "default DNS config should have local DNS service enabled")
|
||||
@ -158,12 +168,12 @@ func TestGetNetworkMap_DNSConfigSync(t *testing.T) {
|
||||
err = am.Store.SaveAccount(account)
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedAccountDNSConfig, err := am.GetNetworkMap(dnsPeer1Key)
|
||||
updatedAccountDNSConfig, err := am.GetNetworkMap(peer1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, updatedAccountDNSConfig.DNSConfig.CustomZones, 0, "updated DNS config should have no custom zone when peer belongs to a disabled group")
|
||||
require.False(t, updatedAccountDNSConfig.DNSConfig.ServiceEnable, "updated DNS config should have local DNS service disabled when peer belongs to a disabled group")
|
||||
|
||||
peer2AccountDNSConfig, err := am.GetNetworkMap(dnsPeer2Key)
|
||||
peer2AccountDNSConfig, err := am.GetNetworkMap(peer2.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer2AccountDNSConfig.DNSConfig.CustomZones, 1, "DNS config should have one custom zone for peers not in the disabled group")
|
||||
require.True(t, peer2AccountDNSConfig.DNSConfig.ServiceEnable, "DNS config should have DNS service enabled for peers not in the disabled group")
|
||||
@ -234,9 +244,33 @@ func initTestDNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = am.AddPeer("", dnsAdminUserID, peer1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = am.AddPeer("", dnsAdminUserID, peer2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
account, err = am.Store.GetAccount(account.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer1, err = account.FindPeerByPubKey(peer1.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = account.FindPeerByPubKey(peer2.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newGroup1 := &Group{
|
||||
ID: dnsGroup1ID,
|
||||
Peers: []string{peer1.Key},
|
||||
Peers: []string{peer1.ID},
|
||||
Name: dnsGroup1ID,
|
||||
}
|
||||
|
||||
@ -253,14 +287,5 @@ func initTestDNSAccount(t *testing.T, am *DefaultAccountManager) (*Account, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = am.AddPeer("", dnsAdminUserID, peer1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = am.AddPeer("", dnsAdminUserID, peer2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
return am.Store.GetAccount(account.Id)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/rs/xid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -20,6 +21,7 @@ type FileStore struct {
|
||||
Accounts map[string]*Account
|
||||
SetupKeyID2AccountID map[string]string `json:"-"`
|
||||
PeerKeyID2AccountID map[string]string `json:"-"`
|
||||
PeerID2AccountID map[string]string `json:"-"`
|
||||
UserID2AccountID map[string]string `json:"-"`
|
||||
PrivateDomain2AccountID map[string]string `json:"-"`
|
||||
InstallationID string
|
||||
@ -53,6 +55,7 @@ func restore(file string) (*FileStore, error) {
|
||||
PeerKeyID2AccountID: make(map[string]string),
|
||||
UserID2AccountID: make(map[string]string),
|
||||
PrivateDomain2AccountID: make(map[string]string),
|
||||
PeerID2AccountID: make(map[string]string),
|
||||
storeFile: file,
|
||||
}
|
||||
|
||||
@ -75,6 +78,7 @@ func restore(file string) (*FileStore, error) {
|
||||
store.PeerKeyID2AccountID = make(map[string]string)
|
||||
store.UserID2AccountID = make(map[string]string)
|
||||
store.PrivateDomain2AccountID = make(map[string]string)
|
||||
store.PeerID2AccountID = make(map[string]string)
|
||||
|
||||
for accountID, account := range store.Accounts {
|
||||
for setupKeyId := range account.SetupKeys {
|
||||
@ -83,6 +87,7 @@ func restore(file string) (*FileStore, error) {
|
||||
|
||||
for _, peer := range account.Peers {
|
||||
store.PeerKeyID2AccountID[peer.Key] = accountID
|
||||
store.PeerID2AccountID[peer.ID] = accountID
|
||||
// reset all peers to status = Disconnected
|
||||
if peer.Status != nil && peer.Status.Connected {
|
||||
peer.Status.Connected = false
|
||||
@ -118,6 +123,47 @@ func restore(file string) (*FileStore, error) {
|
||||
route.Groups = []string{allGroup.ID}
|
||||
}
|
||||
}
|
||||
|
||||
// migration to Peer.ID from Peer.Key.
|
||||
// Old peers that require migration have an empty Peer.ID in the store.json.
|
||||
// Generate new ID with xid for these peers.
|
||||
// Set the Peer.ID to the newly generated value.
|
||||
// Replace all the mentions of Peer.Key as ID (groups and routes).
|
||||
// Swap Peer.Key with Peer.ID in the Account.Peers map.
|
||||
migrationPeers := make(map[string]*Peer) // key to Peer
|
||||
for key, peer := range account.Peers {
|
||||
if peer.ID != "" {
|
||||
continue
|
||||
}
|
||||
id := xid.New().String()
|
||||
peer.ID = id
|
||||
migrationPeers[key] = peer
|
||||
}
|
||||
|
||||
if len(migrationPeers) > 0 {
|
||||
|
||||
// swap Peer.Key with Peer.ID in the Account.Peers map.
|
||||
for key, peer := range migrationPeers {
|
||||
delete(account.Peers, key)
|
||||
account.Peers[peer.ID] = peer
|
||||
store.PeerID2AccountID[peer.ID] = accountID
|
||||
}
|
||||
|
||||
// detect groups that have Peer.Key as a reference and replace it with ID.
|
||||
for _, group := range account.Groups {
|
||||
for i, peer := range group.Peers {
|
||||
if p, ok := migrationPeers[peer]; ok {
|
||||
group.Peers[i] = p.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
// detect routes that have Peer.Key as a reference and replace it with ID.
|
||||
for _, route := range account.Routes {
|
||||
if peer, ok := migrationPeers[route.Peer]; ok {
|
||||
route.Peer = peer.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we need this persist to apply changes we made to account.Peers (we set them to Disconnected)
|
||||
@ -183,6 +229,7 @@ func (s *FileStore) SaveAccount(account *Account) error {
|
||||
// enforce peer to account index and delete peer to route indexes for rebuild
|
||||
for _, peer := range accountCopy.Peers {
|
||||
s.PeerKeyID2AccountID[peer.Key] = accountCopy.Id
|
||||
s.PeerID2AccountID[peer.ID] = accountCopy.Id
|
||||
}
|
||||
|
||||
for _, user := range accountCopy.Users {
|
||||
@ -284,6 +331,24 @@ func (s *FileStore) GetAccountByUser(userID string) (*Account, error) {
|
||||
return account.Copy(), nil
|
||||
}
|
||||
|
||||
// GetAccountByPeerID returns an account for a given peer ID
|
||||
func (s *FileStore) GetAccountByPeerID(peerID string) (*Account, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
accountID, accountIDFound := s.PeerID2AccountID[peerID]
|
||||
if !accountIDFound {
|
||||
return nil, status.Errorf(status.NotFound, "provided peer ID doesn't exists %s", peerID)
|
||||
}
|
||||
|
||||
account, err := s.getAccount(accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account.Copy(), nil
|
||||
}
|
||||
|
||||
// GetAccountByPeerPubKey returns an account for a given peer WireGuard public key
|
||||
func (s *FileStore) GetAccountByPeerPubKey(peerKey string) (*Account, error) {
|
||||
s.mux.Lock()
|
||||
@ -319,7 +384,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.
|
||||
// PeerStatus will be saved eventually when some other changes occur.
|
||||
func (s *FileStore) SavePeerStatus(accountID, peerKey string, peerStatus PeerStatus) error {
|
||||
func (s *FileStore) SavePeerStatus(accountID, peerID string, peerStatus PeerStatus) error {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
@ -328,9 +393,9 @@ func (s *FileStore) SavePeerStatus(accountID, peerKey string, peerStatus PeerSta
|
||||
return err
|
||||
}
|
||||
|
||||
peer := account.Peers[peerKey]
|
||||
peer := account.Peers[peerID]
|
||||
if peer == nil {
|
||||
return status.Errorf(status.NotFound, "peer %s not found", peerKey)
|
||||
return status.Errorf(status.NotFound, "peer %s not found", peerID)
|
||||
}
|
||||
|
||||
peer.Status = &peerStatus
|
||||
|
@ -244,6 +244,7 @@ func TestFileStore_SavePeerStatus(t *testing.T) {
|
||||
// save new status of existing peer
|
||||
account.Peers["testpeer"] = &Peer{
|
||||
Key: "peerkey",
|
||||
ID: "testpeer",
|
||||
SetupKey: "peerkeysetupkey",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
Meta: PeerSystemMeta{},
|
||||
|
@ -88,6 +88,13 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
|
||||
return err
|
||||
}
|
||||
|
||||
err = am.updateAccountPeers(account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the following snippet tracks the activity and stores the group events in the event store.
|
||||
// It has to happen after all the operations have been successfully performed.
|
||||
addedPeers := make([]string, 0)
|
||||
removedPeers := make([]string, 0)
|
||||
if exists {
|
||||
@ -104,7 +111,7 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
|
||||
log.Errorf("peer %s not found under account %s while saving group", p, accountID)
|
||||
continue
|
||||
}
|
||||
am.storeEvent(userID, peer.IP.String(), accountID, activity.GroupAddedToPeer,
|
||||
am.storeEvent(userID, peer.ID, accountID, activity.GroupAddedToPeer,
|
||||
map[string]any{"group": newGroup.Name, "group_id": newGroup.ID, "peer_ip": peer.IP.String(),
|
||||
"peer_fqdn": peer.FQDN(am.GetDNSDomain())})
|
||||
}
|
||||
@ -115,12 +122,12 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
|
||||
log.Errorf("peer %s not found under account %s while saving group", p, accountID)
|
||||
continue
|
||||
}
|
||||
am.storeEvent(userID, peer.IP.String(), accountID, activity.GroupRemovedFromPeer,
|
||||
am.storeEvent(userID, peer.ID, accountID, activity.GroupRemovedFromPeer,
|
||||
map[string]any{"group": newGroup.Name, "group_id": newGroup.ID, "peer_ip": peer.IP.String(),
|
||||
"peer_fqdn": peer.FQDN(am.GetDNSDomain())})
|
||||
}
|
||||
|
||||
return am.updateAccountPeers(account)
|
||||
return nil
|
||||
}
|
||||
|
||||
// difference returns the elements in `a` that aren't in `b`.
|
||||
@ -230,7 +237,7 @@ func (am *DefaultAccountManager) ListGroups(accountID string) ([]*Group, error)
|
||||
}
|
||||
|
||||
// GroupAddPeer appends peer to the group
|
||||
func (am *DefaultAccountManager) GroupAddPeer(accountID, groupID, peerKey string) error {
|
||||
func (am *DefaultAccountManager) GroupAddPeer(accountID, groupID, peerID string) error {
|
||||
|
||||
unlock := am.Store.AcquireAccountLock(accountID)
|
||||
defer unlock()
|
||||
@ -247,13 +254,13 @@ func (am *DefaultAccountManager) GroupAddPeer(accountID, groupID, peerKey string
|
||||
|
||||
add := true
|
||||
for _, itemID := range group.Peers {
|
||||
if itemID == peerKey {
|
||||
if itemID == peerID {
|
||||
add = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if add {
|
||||
group.Peers = append(group.Peers, peerKey)
|
||||
group.Peers = append(group.Peers, peerID)
|
||||
}
|
||||
|
||||
account.Network.IncSerial()
|
||||
|
@ -111,7 +111,7 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
|
||||
return status.Errorf(codes.InvalidArgument, "provided wgPubKey %s is invalid", peerKey.String())
|
||||
}
|
||||
|
||||
peer, err := s.accountManager.GetPeer(peerKey.String())
|
||||
peer, err := s.accountManager.GetPeerByKey(peerKey.String())
|
||||
if err != nil {
|
||||
p, _ := gPeer.FromContext(srv.Context())
|
||||
msg := status.Errorf(codes.PermissionDenied, "provided peer with the key wgPubKey %s is not registered, remote addr is %s", peerKey.String(), p.Addr.String())
|
||||
@ -134,14 +134,14 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
|
||||
return err
|
||||
}
|
||||
|
||||
updates := s.peersUpdateManager.CreateChannel(peerKey.String())
|
||||
updates := s.peersUpdateManager.CreateChannel(peer.ID)
|
||||
err = s.accountManager.MarkPeerConnected(peerKey.String(), true)
|
||||
if err != nil {
|
||||
log.Warnf("failed marking peer as connected %s %v", peerKey, err)
|
||||
}
|
||||
|
||||
if s.config.TURNConfig.TimeBasedCredentials {
|
||||
s.turnCredentialsManager.SetupRefresh(peerKey.String())
|
||||
s.turnCredentialsManager.SetupRefresh(peer.ID)
|
||||
}
|
||||
// keep a connection to the peer and send updates when available
|
||||
for {
|
||||
@ -171,7 +171,7 @@ func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementServi
|
||||
case <-srv.Context().Done():
|
||||
// happens when connection drops, e.g. client disconnects
|
||||
log.Debugf("stream of peer %s has been closed", peerKey.String())
|
||||
s.peersUpdateManager.CloseChannel(peerKey.String())
|
||||
s.peersUpdateManager.CloseChannel(peer.ID)
|
||||
s.turnCredentialsManager.CancelRefresh(peerKey.String())
|
||||
err = s.accountManager.MarkPeerConnected(peerKey.String(), false)
|
||||
if err != nil {
|
||||
@ -252,19 +252,19 @@ func (s *GRPCServer) registerPeer(peerKey wgtypes.Key, req *proto.LoginRequest)
|
||||
}
|
||||
|
||||
// todo move to DefaultAccountManager the code below
|
||||
networkMap, err := s.accountManager.GetNetworkMap(peer.Key)
|
||||
networkMap, err := s.accountManager.GetNetworkMap(peer.ID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "unable to fetch network map after registering peer, error: %v", err)
|
||||
}
|
||||
// notify other peers of our registration
|
||||
for _, remotePeer := range networkMap.Peers {
|
||||
remotePeerNetworkMap, err := s.accountManager.GetNetworkMap(remotePeer.Key)
|
||||
remotePeerNetworkMap, err := s.accountManager.GetNetworkMap(remotePeer.ID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "unable to fetch network map after registering peer, error: %v", err)
|
||||
}
|
||||
|
||||
update := toSyncResponse(s.config, remotePeer, nil, remotePeerNetworkMap, s.accountManager.GetDNSDomain())
|
||||
err = s.peersUpdateManager.SendUpdate(remotePeer.Key, &UpdateMessage{Update: update})
|
||||
err = s.peersUpdateManager.SendUpdate(remotePeer.ID, &UpdateMessage{Update: update})
|
||||
if err != nil {
|
||||
// todo rethink if we should keep this return
|
||||
return nil, status.Errorf(codes.Internal, "unable to send update after registering peer, error: %v", err)
|
||||
@ -299,7 +299,7 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid request message")
|
||||
}
|
||||
|
||||
peer, err := s.accountManager.GetPeer(peerKey.String())
|
||||
peer, err := s.accountManager.GetPeerByKey(peerKey.String())
|
||||
if err != nil {
|
||||
if errStatus, ok := internalStatus.FromError(err); ok && errStatus.Type() == internalStatus.NotFound {
|
||||
// peer doesn't exist -> check if setup key was provided
|
||||
@ -324,7 +324,7 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p
|
||||
}
|
||||
} else if loginReq.GetMeta() != nil {
|
||||
// update peer's system meta data on Login
|
||||
err = s.accountManager.UpdatePeerMeta(peerKey.String(), PeerSystemMeta{
|
||||
err = s.accountManager.UpdatePeerMeta(peer.ID, PeerSystemMeta{
|
||||
Hostname: loginReq.GetMeta().GetHostname(),
|
||||
GoOS: loginReq.GetMeta().GetGoOS(),
|
||||
Kernel: loginReq.GetMeta().GetKernel(),
|
||||
@ -347,13 +347,13 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p
|
||||
}
|
||||
|
||||
if len(sshKey) > 0 {
|
||||
err = s.accountManager.UpdatePeerSSHKey(peerKey.String(), string(sshKey))
|
||||
err = s.accountManager.UpdatePeerSSHKey(peer.ID, string(sshKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
network, err := s.accountManager.GetPeerNetwork(peer.Key)
|
||||
network, err := s.accountManager.GetPeerNetwork(peer.ID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed getting peer network on login")
|
||||
}
|
||||
@ -491,9 +491,9 @@ func (s *GRPCServer) IsHealthy(ctx context.Context, req *proto.Empty) (*proto.Em
|
||||
|
||||
// sendInitialSync sends initial proto.SyncResponse to the peer requesting synchronization
|
||||
func (s *GRPCServer) sendInitialSync(peerKey wgtypes.Key, peer *Peer, srv proto.ManagementService_SyncServer) error {
|
||||
networkMap, err := s.accountManager.GetNetworkMap(peer.Key)
|
||||
networkMap, err := s.accountManager.GetNetworkMap(peer.ID)
|
||||
if err != nil {
|
||||
log.Warnf("error getting a list of peers for a peer %s", peer.Key)
|
||||
log.Warnf("error getting a list of peers for a peer %s", peer.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -96,10 +96,16 @@ func (h *Groups) UpdateGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var peers []string
|
||||
if req.Peers == nil {
|
||||
peers = make([]string, 0)
|
||||
} else {
|
||||
peers = *req.Peers
|
||||
}
|
||||
group := server.Group{
|
||||
ID: groupID,
|
||||
Name: *req.Name,
|
||||
Peers: peerIPsToKeys(account, req.Peers),
|
||||
Peers: peers,
|
||||
}
|
||||
|
||||
if err := h.accountManager.SaveGroup(account.Id, user.Id, &group); err != nil {
|
||||
@ -191,10 +197,9 @@ func (h *Groups) PatchGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
Values: peerKeys,
|
||||
})
|
||||
case api.GroupPatchOperationOpAdd:
|
||||
peerKeys := peerIPsToKeys(account, &patch.Value)
|
||||
operations = append(operations, server.GroupUpdateOperation{
|
||||
Type: server.InsertPeersToGroup,
|
||||
Values: peerKeys,
|
||||
Values: patch.Value,
|
||||
})
|
||||
default:
|
||||
util.WriteError(status.Errorf(status.InvalidArgument,
|
||||
@ -237,10 +242,16 @@ func (h *Groups) CreateGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var peers []string
|
||||
if req.Peers == nil {
|
||||
peers = make([]string, 0)
|
||||
} else {
|
||||
peers = *req.Peers
|
||||
}
|
||||
group := server.Group{
|
||||
ID: xid.New().String(),
|
||||
Name: req.Name,
|
||||
Peers: peerIPsToKeys(account, req.Peers),
|
||||
Peers: peers,
|
||||
}
|
||||
|
||||
err = h.accountManager.SaveGroup(account.Id, user.Id, &group)
|
||||
@ -359,7 +370,7 @@ func toGroupResponse(account *server.Account, group *server.Group) *api.Group {
|
||||
continue
|
||||
}
|
||||
peerResp := api.PeerMinimum{
|
||||
Id: peer.IP.String(),
|
||||
Id: peer.ID,
|
||||
Name: peer.Name,
|
||||
}
|
||||
cache[pid] = peerResp
|
||||
|
@ -22,8 +22,8 @@ import (
|
||||
)
|
||||
|
||||
var TestPeers = map[string]*server.Peer{
|
||||
"A": {Key: "A", IP: net.ParseIP("100.100.100.100")},
|
||||
"B": {Key: "B", IP: net.ParseIP("200.200.200.200")},
|
||||
"A": {Key: "A", ID: "peer-A-ID", IP: net.ParseIP("100.100.100.100")},
|
||||
"B": {Key: "B", ID: "peer-B-ID", IP: net.ParseIP("200.200.200.200")},
|
||||
}
|
||||
|
||||
func initGroupTestData(user *server.User, groups ...*server.Group) *Groups {
|
||||
@ -269,8 +269,8 @@ func TestWriteGroup(t *testing.T) {
|
||||
Id: "id-existed",
|
||||
PeersCount: 2,
|
||||
Peers: []api.PeerMinimum{
|
||||
{Id: "100.100.100.100"},
|
||||
{Id: "200.200.200.200"}},
|
||||
{Id: "peer-A-ID"},
|
||||
{Id: "peer-B-ID"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func NewPeers(accountManager server.AccountManager, authAudience string) *Peers
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Peers) updatePeer(account *server.Account, user *server.User, peer *server.Peer, w http.ResponseWriter, r *http.Request) {
|
||||
func (h *Peers) updatePeer(account *server.Account, user *server.User, peerID string, w http.ResponseWriter, r *http.Request) {
|
||||
req := &api.PutApiPeersIdJSONBody{}
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
@ -35,8 +35,8 @@ func (h *Peers) updatePeer(account *server.Account, user *server.User, peer *ser
|
||||
return
|
||||
}
|
||||
|
||||
update := &server.Peer{Key: peer.Key, SSHEnabled: req.SshEnabled, Name: req.Name}
|
||||
peer, err = h.accountManager.UpdatePeer(account.Id, user.Id, update)
|
||||
update := &server.Peer{ID: peerID, SSHEnabled: req.SshEnabled, Name: req.Name}
|
||||
peer, err := h.accountManager.UpdatePeer(account.Id, user.Id, update)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
@ -45,8 +45,8 @@ func (h *Peers) updatePeer(account *server.Account, user *server.User, peer *ser
|
||||
util.WriteJSONObject(w, toPeerResponse(peer, account, dnsDomain))
|
||||
}
|
||||
|
||||
func (h *Peers) deletePeer(accountID, userID string, peer *server.Peer, w http.ResponseWriter, r *http.Request) {
|
||||
_, err := h.accountManager.DeletePeer(accountID, peer.Key, userID)
|
||||
func (h *Peers) deletePeer(accountID, userID string, peerID string, w http.ResponseWriter) {
|
||||
_, err := h.accountManager.DeletePeer(accountID, peerID, userID)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
@ -62,31 +62,19 @@ func (h *Peers) HandlePeer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
vars := mux.Vars(r)
|
||||
peerId := vars["id"] //effectively peer IP address
|
||||
if len(peerId) == 0 {
|
||||
peerID := vars["id"]
|
||||
if len(peerID) == 0 {
|
||||
util.WriteError(status.Errorf(status.InvalidArgument, "invalid peer ID"), w)
|
||||
return
|
||||
}
|
||||
|
||||
peer, err := h.accountManager.GetPeerByIP(account.Id, peerId)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
dnsDomain := h.accountManager.GetDNSDomain()
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodDelete:
|
||||
h.deletePeer(account.Id, user.Id, peer, w, r)
|
||||
h.deletePeer(account.Id, user.Id, peerID, w)
|
||||
return
|
||||
case http.MethodPut:
|
||||
h.updatePeer(account, user, peer, w, r)
|
||||
h.updatePeer(account, user, peerID, w, r)
|
||||
return
|
||||
case http.MethodGet:
|
||||
util.WriteJSONObject(w, toPeerResponse(peer, account, dnsDomain))
|
||||
return
|
||||
|
||||
default:
|
||||
util.WriteError(status.Errorf(status.NotFound, "unknown METHOD"), w)
|
||||
}
|
||||
@ -132,7 +120,7 @@ func toPeerResponse(peer *server.Peer, account *server.Account, dnsDomain string
|
||||
}
|
||||
groupsChecked[group.ID] = struct{}{}
|
||||
for _, pk := range group.Peers {
|
||||
if pk == peer.Key {
|
||||
if pk == peer.ID {
|
||||
info := api.GroupMinimum{
|
||||
Id: group.ID,
|
||||
Name: group.Name,
|
||||
@ -149,7 +137,7 @@ func toPeerResponse(peer *server.Peer, account *server.Account, dnsDomain string
|
||||
fqdn = peer.DNSLabel
|
||||
}
|
||||
return &api.Peer{
|
||||
Id: peer.IP.String(),
|
||||
Id: peer.ID,
|
||||
Name: peer.Name,
|
||||
Ip: peer.IP.String(),
|
||||
Connected: peer.Status.Connected,
|
||||
|
@ -45,7 +45,7 @@ func (h *Routes) GetAllRoutesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
apiRoutes := make([]*api.Route, 0)
|
||||
for _, r := range routes {
|
||||
apiRoutes = append(apiRoutes, toRouteResponse(account, r))
|
||||
apiRoutes = append(apiRoutes, toRouteResponse(r))
|
||||
}
|
||||
|
||||
util.WriteJSONObject(w, apiRoutes)
|
||||
@ -85,7 +85,7 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp := toRouteResponse(account, newRoute)
|
||||
resp := toRouteResponse(newRoute)
|
||||
|
||||
util.WriteJSONObject(w, &resp)
|
||||
}
|
||||
@ -126,16 +126,6 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
peerKey := req.Peer
|
||||
if req.Peer != "" {
|
||||
peer := account.GetPeerByIP(req.Peer)
|
||||
if peer == nil {
|
||||
util.WriteError(status.Errorf(status.NotFound, "peer %s not found", req.Peer), w)
|
||||
return
|
||||
}
|
||||
peerKey = peer.Key
|
||||
}
|
||||
|
||||
if utf8.RuneCountInString(req.NetworkId) > route.MaxNetIDChar || req.NetworkId == "" {
|
||||
util.WriteError(status.Errorf(status.InvalidArgument,
|
||||
"identifier should be between 1 and %d", route.MaxNetIDChar), w)
|
||||
@ -148,7 +138,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
NetID: req.NetworkId,
|
||||
NetworkType: prefixType,
|
||||
Masquerade: req.Masquerade,
|
||||
Peer: peerKey,
|
||||
Peer: req.Peer,
|
||||
Metric: req.Metric,
|
||||
Description: req.Description,
|
||||
Enabled: req.Enabled,
|
||||
@ -161,7 +151,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp := toRouteResponse(account, newRoute)
|
||||
resp := toRouteResponse(newRoute)
|
||||
|
||||
util.WriteJSONObject(w, &resp)
|
||||
}
|
||||
@ -245,18 +235,9 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
"value field only accepts 1 value, got %d", len(patch.Value)), w)
|
||||
return
|
||||
}
|
||||
peerValue := patch.Value
|
||||
if patch.Value[0] != "" {
|
||||
peer, err := h.accountManager.GetPeerByIP(account.Id, patch.Value[0])
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
}
|
||||
peerValue = []string{peer.Key}
|
||||
}
|
||||
operations = append(operations, server.RouteUpdateOperation{
|
||||
Type: server.UpdateRoutePeer,
|
||||
Values: peerValue,
|
||||
Values: patch.Value,
|
||||
})
|
||||
case api.RoutePatchOperationPathMetric:
|
||||
if patch.Op != api.RoutePatchOperationOpReplace {
|
||||
@ -305,13 +286,13 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
route, err := h.accountManager.UpdateRoute(account.Id, routeID, operations)
|
||||
root, err := h.accountManager.UpdateRoute(account.Id, routeID, operations)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
resp := toRouteResponse(account, route)
|
||||
resp := toRouteResponse(root)
|
||||
|
||||
util.WriteJSONObject(w, &resp)
|
||||
}
|
||||
@ -361,25 +342,16 @@ func (h *Routes) GetRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
util.WriteJSONObject(w, toRouteResponse(account, foundRoute))
|
||||
util.WriteJSONObject(w, toRouteResponse(foundRoute))
|
||||
}
|
||||
|
||||
func toRouteResponse(account *server.Account, serverRoute *route.Route) *api.Route {
|
||||
var peerIP string
|
||||
if serverRoute.Peer != "" {
|
||||
peer, found := account.Peers[serverRoute.Peer]
|
||||
if !found {
|
||||
panic("peer ID not found")
|
||||
}
|
||||
peerIP = peer.IP.String()
|
||||
}
|
||||
|
||||
func toRouteResponse(serverRoute *route.Route) *api.Route {
|
||||
return &api.Route{
|
||||
Id: serverRoute.ID,
|
||||
Description: serverRoute.Description,
|
||||
NetworkId: serverRoute.NetID,
|
||||
Enabled: serverRoute.Enabled,
|
||||
Peer: peerIP,
|
||||
Peer: serverRoute.Peer,
|
||||
Network: serverRoute.Network.String(),
|
||||
NetworkType: serverRoute.NetworkType.String(),
|
||||
Masquerade: serverRoute.Masquerade,
|
||||
|
@ -24,8 +24,9 @@ import (
|
||||
const (
|
||||
existingRouteID = "existingRouteID"
|
||||
notFoundRouteID = "notFoundRouteID"
|
||||
existingPeerID = "100.64.0.100"
|
||||
notFoundPeerID = "100.64.0.200"
|
||||
existingPeerIP = "100.64.0.100"
|
||||
existingPeerID = "peer-id"
|
||||
notFoundPeerID = "nonExistingPeer"
|
||||
existingPeerKey = "existingPeerKey"
|
||||
testAccountID = "test_id"
|
||||
existingGroupID = "testGroup"
|
||||
@ -47,9 +48,10 @@ var testingAccount = &server.Account{
|
||||
Id: testAccountID,
|
||||
Domain: "hotmail.com",
|
||||
Peers: map[string]*server.Peer{
|
||||
existingPeerKey: {
|
||||
existingPeerID: {
|
||||
Key: existingPeerKey,
|
||||
IP: netip.MustParseAddr(existingPeerID).AsSlice(),
|
||||
IP: netip.MustParseAddr(existingPeerIP).AsSlice(),
|
||||
ID: existingPeerID,
|
||||
},
|
||||
},
|
||||
Users: map[string]*server.User{
|
||||
@ -66,18 +68,15 @@ func initRoutesTestData() *Routes {
|
||||
}
|
||||
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
|
||||
},
|
||||
CreateRouteFunc: func(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, _ string) (*route.Route, error) {
|
||||
|
||||
peer := testingAccount.GetPeerByIP(peerIP)
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.NotFound, "peer %s not found", peerIP)
|
||||
CreateRouteFunc: func(accountID string, network, peerID, description, netID string, masquerade bool, metric int, groups []string, enabled bool, _ string) (*route.Route, error) {
|
||||
if peerID == notFoundPeerID {
|
||||
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", peerID)
|
||||
}
|
||||
|
||||
networkType, p, _ := route.ParseNetwork(network)
|
||||
return &route.Route{
|
||||
ID: existingRouteID,
|
||||
NetID: netID,
|
||||
Peer: peer.Key,
|
||||
Peer: peerID,
|
||||
Network: p,
|
||||
NetworkType: networkType,
|
||||
Description: description,
|
||||
@ -86,7 +85,10 @@ func initRoutesTestData() *Routes {
|
||||
Groups: groups,
|
||||
}, nil
|
||||
},
|
||||
SaveRouteFunc: func(_, _ string, _ *route.Route) error {
|
||||
SaveRouteFunc: func(_, _ string, r *route.Route) error {
|
||||
if r.Peer == notFoundPeerID {
|
||||
return status.Errorf(status.InvalidArgument, "peer with ID %s not found", r.Peer)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
DeleteRouteFunc: func(_ string, routeID string, _ string) error {
|
||||
@ -119,6 +121,9 @@ func initRoutesTestData() *Routes {
|
||||
routeToUpdate.NetID = operation.Values[0]
|
||||
case server.UpdateRoutePeer:
|
||||
routeToUpdate.Peer = operation.Values[0]
|
||||
if routeToUpdate.Peer == notFoundPeerID {
|
||||
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", routeToUpdate.Peer)
|
||||
}
|
||||
case server.UpdateRouteMetric:
|
||||
routeToUpdate.Metric, _ = strconv.Atoi(operation.Values[0])
|
||||
case server.UpdateRouteMasquerade:
|
||||
@ -166,7 +171,7 @@ func TestRoutesHandlers(t *testing.T) {
|
||||
requestPath: "/api/routes/" + existingRouteID,
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedBody: true,
|
||||
expectedRoute: toRouteResponse(testingAccount, baseExistingRoute),
|
||||
expectedRoute: toRouteResponse(baseExistingRoute),
|
||||
},
|
||||
{
|
||||
name: "Get Not Existing Route",
|
||||
@ -212,7 +217,7 @@ func TestRoutesHandlers(t *testing.T) {
|
||||
requestType: http.MethodPost,
|
||||
requestPath: "/api/routes",
|
||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", notFoundPeerID, existingGroupID)),
|
||||
expectedStatus: http.StatusNotFound,
|
||||
expectedStatus: http.StatusUnprocessableEntity,
|
||||
expectedBody: false,
|
||||
},
|
||||
{
|
||||
@ -263,7 +268,7 @@ func TestRoutesHandlers(t *testing.T) {
|
||||
requestType: http.MethodPut,
|
||||
requestPath: "/api/routes/" + existingRouteID,
|
||||
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"]}", notFoundPeerID, existingGroupID)),
|
||||
expectedStatus: http.StatusNotFound,
|
||||
expectedStatus: http.StatusUnprocessableEntity,
|
||||
expectedBody: false,
|
||||
},
|
||||
{
|
||||
@ -326,7 +331,7 @@ func TestRoutesHandlers(t *testing.T) {
|
||||
requestType: http.MethodPatch,
|
||||
requestPath: "/api/routes/" + existingRouteID,
|
||||
requestBody: bytes.NewBufferString(fmt.Sprintf("[{\"op\":\"replace\",\"path\":\"peer\",\"value\":[\"%s\"]}]", notFoundPeerID)),
|
||||
expectedStatus: http.StatusNotFound,
|
||||
expectedStatus: http.StatusUnprocessableEntity,
|
||||
expectedBody: false,
|
||||
},
|
||||
{
|
||||
|
@ -207,7 +207,7 @@ func (w *Worker) generateProperties() properties {
|
||||
osUIClients[uiOSKey] = osUICount + 1
|
||||
}
|
||||
|
||||
_, connected := connections[peer.Key]
|
||||
_, connected := connections[peer.ID]
|
||||
if connected || peer.Status.LastSeen.After(w.lastRun) {
|
||||
activePeersLastDay++
|
||||
osActiveKey := osKey + "_active"
|
||||
|
@ -42,8 +42,8 @@ type MockAccountManager struct {
|
||||
DeleteRuleFunc func(accountID, ruleID, userID string) error
|
||||
ListRulesFunc func(accountID, userID string) ([]*server.Rule, error)
|
||||
GetUsersFromAccountFunc func(accountID, userID string) ([]*server.UserInfo, error)
|
||||
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
|
||||
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
|
||||
UpdatePeerMetaFunc func(peerID string, meta server.PeerSystemMeta) error
|
||||
UpdatePeerSSHKeyFunc func(peerID string, sshKey string) error
|
||||
UpdatePeerFunc func(accountID, userID string, peer *server.Peer) (*server.Peer, error)
|
||||
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
|
||||
GetRouteFunc func(accountID, routeID, userID string) (*route.Route, error)
|
||||
@ -77,9 +77,9 @@ func (am *MockAccountManager) GetUsersFromAccount(accountID string, userID strin
|
||||
}
|
||||
|
||||
// DeletePeer mock implementation of DeletePeer from server.AccountManager interface
|
||||
func (am *MockAccountManager) DeletePeer(accountID, peerKey, userID string) (*server.Peer, error) {
|
||||
func (am *MockAccountManager) DeletePeer(accountID, peerID, userID string) (*server.Peer, error) {
|
||||
if am.DeletePeerFunc != nil {
|
||||
return am.DeletePeerFunc(accountID, peerKey, userID)
|
||||
return am.DeletePeerFunc(accountID, peerID, userID)
|
||||
}
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeletePeer is not implemented")
|
||||
}
|
||||
@ -143,11 +143,11 @@ func (am *MockAccountManager) AccountExists(accountId string) (*bool, error) {
|
||||
}
|
||||
|
||||
// GetPeer mock implementation of GetPeer from server.AccountManager interface
|
||||
func (am *MockAccountManager) GetPeer(peerKey string) (*server.Peer, error) {
|
||||
func (am *MockAccountManager) GetPeerByKey(peerKey string) (*server.Peer, error) {
|
||||
if am.GetPeerFunc != nil {
|
||||
return am.GetPeerFunc(peerKey)
|
||||
}
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPeer is not implemented")
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPeerByKey is not implemented")
|
||||
}
|
||||
|
||||
// MarkPeerConnected mock implementation of MarkPeerConnected from server.AccountManager interface
|
||||
@ -299,9 +299,9 @@ func (am *MockAccountManager) ListRules(accountID, userID string) ([]*server.Rul
|
||||
}
|
||||
|
||||
// UpdatePeerMeta mock implementation of UpdatePeerMeta from server.AccountManager interface
|
||||
func (am *MockAccountManager) UpdatePeerMeta(peerKey string, meta server.PeerSystemMeta) error {
|
||||
func (am *MockAccountManager) UpdatePeerMeta(peerID string, meta server.PeerSystemMeta) error {
|
||||
if am.UpdatePeerMetaFunc != nil {
|
||||
return am.UpdatePeerMetaFunc(peerKey, meta)
|
||||
return am.UpdatePeerMetaFunc(peerID, meta)
|
||||
}
|
||||
return status.Errorf(codes.Unimplemented, "method UpdatePeerMetaFunc is not implemented")
|
||||
}
|
||||
@ -315,9 +315,9 @@ func (am *MockAccountManager) IsUserAdmin(claims jwtclaims.AuthorizationClaims)
|
||||
}
|
||||
|
||||
// UpdatePeerSSHKey mocks UpdatePeerSSHKey function of the account manager
|
||||
func (am *MockAccountManager) UpdatePeerSSHKey(peerKey string, sshKey string) error {
|
||||
func (am *MockAccountManager) UpdatePeerSSHKey(peerID string, sshKey string) error {
|
||||
if am.UpdatePeerSSHKeyFunc != nil {
|
||||
return am.UpdatePeerSSHKeyFunc(peerKey, sshKey)
|
||||
return am.UpdatePeerSSHKeyFunc(peerID, sshKey)
|
||||
}
|
||||
return status.Errorf(codes.Unimplemented, "method UpdatePeerSSHKey is is not implemented")
|
||||
}
|
||||
@ -331,9 +331,9 @@ func (am *MockAccountManager) UpdatePeer(accountID, userID string, peer *server.
|
||||
}
|
||||
|
||||
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
|
||||
func (am *MockAccountManager) CreateRoute(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
|
||||
func (am *MockAccountManager) CreateRoute(accountID string, network, peerID, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
|
||||
if am.CreateRouteFunc != nil {
|
||||
return am.CreateRouteFunc(accountID, network, peerIP, description, netID, masquerade, metric, groups, enabled, userID)
|
||||
return am.CreateRouteFunc(accountID, network, peerID, description, netID, masquerade, metric, groups, enabled, userID)
|
||||
}
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
nbdns "github.com/netbirdio/netbird/dns"
|
||||
"github.com/netbirdio/netbird/management/server/activity"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/rs/xid"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
@ -34,9 +35,11 @@ type PeerStatus struct {
|
||||
}
|
||||
|
||||
// Peer represents a machine connected to the network.
|
||||
// The Peer is a Wireguard peer identified by a public key
|
||||
// The Peer is a WireGuard peer identified by a public key
|
||||
type Peer struct {
|
||||
// Wireguard public key
|
||||
// ID is an internal ID of the peer
|
||||
ID string
|
||||
// WireGuard public key
|
||||
Key string
|
||||
// A setup key this peer was registered with
|
||||
SetupKey string
|
||||
@ -62,6 +65,7 @@ type Peer struct {
|
||||
// Copy copies Peer object
|
||||
func (p *Peer) Copy() *Peer {
|
||||
return &Peer{
|
||||
ID: p.ID,
|
||||
Key: p.Key,
|
||||
SetupKey: p.SetupKey,
|
||||
IP: p.IP,
|
||||
@ -97,7 +101,7 @@ func (p *PeerStatus) Copy() *PeerStatus {
|
||||
}
|
||||
|
||||
// GetPeer looks up peer by its public WireGuard key
|
||||
func (am *DefaultAccountManager) GetPeer(peerPubKey string) (*Peer, error) {
|
||||
func (am *DefaultAccountManager) GetPeerByKey(peerPubKey string) (*Peer, error) {
|
||||
|
||||
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
|
||||
if err != nil {
|
||||
@ -130,14 +134,14 @@ func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, er
|
||||
}
|
||||
p := peer.Copy()
|
||||
peers = append(peers, p)
|
||||
peersMap[peer.Key] = p
|
||||
peersMap[peer.ID] = p
|
||||
}
|
||||
|
||||
// fetch all the peers that have access to the user's peers
|
||||
for _, peer := range peers {
|
||||
aclPeers := account.getPeersByACL(peer.Key)
|
||||
aclPeers := account.getPeersByACL(peer.ID)
|
||||
for _, p := range aclPeers {
|
||||
peersMap[p.Key] = p
|
||||
peersMap[p.ID] = p
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +181,7 @@ func (am *DefaultAccountManager) MarkPeerConnected(peerPubKey string, connected
|
||||
peer.Status = newStatus
|
||||
account.UpdatePeer(peer)
|
||||
|
||||
err = am.Store.SavePeerStatus(account.Id, peerPubKey, *newStatus)
|
||||
err = am.Store.SavePeerStatus(account.Id, peer.ID, *newStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -195,10 +199,9 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO Peer.ID migration: we will need to replace search by ID here
|
||||
peer, err := account.FindPeerByPubKey(update.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
peer := account.GetPeer(update.ID)
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.NotFound, "peer %s not found", update.ID)
|
||||
}
|
||||
|
||||
if peer.SSHEnabled != update.SSHEnabled {
|
||||
@ -222,7 +225,7 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
|
||||
|
||||
peer.DNSLabel = newLabel
|
||||
|
||||
am.storeEvent(userID, peer.IP.String(), accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
|
||||
am.storeEvent(userID, peer.ID, accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
|
||||
}
|
||||
|
||||
account.UpdatePeer(peer)
|
||||
@ -241,7 +244,7 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
|
||||
}
|
||||
|
||||
// DeletePeer removes peer from the account by its IP
|
||||
func (am *DefaultAccountManager) DeletePeer(accountID, peerPubKey, userID string) (*Peer, error) {
|
||||
func (am *DefaultAccountManager) DeletePeer(accountID, peerID, userID string) (*Peer, error) {
|
||||
|
||||
unlock := am.Store.AcquireAccountLock(accountID)
|
||||
defer unlock()
|
||||
@ -251,19 +254,19 @@ func (am *DefaultAccountManager) DeletePeer(accountID, peerPubKey, userID string
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer, err := account.FindPeerByPubKey(peerPubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
peer := account.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.NotFound, "peer %s not found", peerID)
|
||||
}
|
||||
|
||||
account.DeletePeer(peerPubKey)
|
||||
account.DeletePeer(peerID)
|
||||
|
||||
err = am.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = am.peersUpdateManager.SendUpdate(peerPubKey,
|
||||
err = am.peersUpdateManager.SendUpdate(peer.ID,
|
||||
&UpdateMessage{
|
||||
Update: &proto.SyncResponse{
|
||||
// fill those field for backward compatibility
|
||||
@ -281,13 +284,12 @@ func (am *DefaultAccountManager) DeletePeer(accountID, peerPubKey, userID string
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO Peer.ID migration: we will need to replace search by Peer.ID here
|
||||
if err := am.updateAccountPeers(account); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
am.peersUpdateManager.CloseChannel(peerPubKey)
|
||||
am.storeEvent(userID, peer.IP.String(), account.Id, activity.PeerRemovedByUser, peer.EventMeta(am.GetDNSDomain()))
|
||||
am.peersUpdateManager.CloseChannel(peerID)
|
||||
am.storeEvent(userID, peer.ID, account.Id, activity.PeerRemovedByUser, peer.EventMeta(am.GetDNSDomain()))
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
@ -312,17 +314,23 @@ func (am *DefaultAccountManager) GetPeerByIP(accountID string, peerIP string) (*
|
||||
}
|
||||
|
||||
// GetNetworkMap returns Network map for a given peer (omits original peer from the Peers result)
|
||||
func (am *DefaultAccountManager) GetNetworkMap(peerPubKey string) (*NetworkMap, error) {
|
||||
func (am *DefaultAccountManager) GetNetworkMap(peerID string) (*NetworkMap, error) {
|
||||
|
||||
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
|
||||
account, err := am.Store.GetAccountByPeerID(peerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aclPeers := account.getPeersByACL(peerPubKey)
|
||||
routesUpdate := account.getRoutesToSync(peerPubKey, aclPeers)
|
||||
peer := account.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.NotFound, "peer with ID %s not found", peerID)
|
||||
}
|
||||
|
||||
dnsManagementStatus := account.getPeerDNSManagementStatus(peerPubKey)
|
||||
aclPeers := account.getPeersByACL(peerID)
|
||||
// Please mind, that the returned route.Route objects will contain Peer.Key instead of Peer.ID.
|
||||
routesUpdate := account.getRoutesToSync(peerID, aclPeers)
|
||||
|
||||
dnsManagementStatus := account.getPeerDNSManagementStatus(peerID)
|
||||
dnsUpdate := nbdns.Config{
|
||||
ServiceEnable: dnsManagementStatus,
|
||||
}
|
||||
@ -334,7 +342,7 @@ func (am *DefaultAccountManager) GetNetworkMap(peerPubKey string) (*NetworkMap,
|
||||
zones = append(zones, peersCustomZone)
|
||||
}
|
||||
dnsUpdate.CustomZones = zones
|
||||
dnsUpdate.NameServerGroups = getPeerNSGroups(account, peerPubKey)
|
||||
dnsUpdate.NameServerGroups = getPeerNSGroups(account, peerID)
|
||||
}
|
||||
|
||||
return &NetworkMap{
|
||||
@ -346,9 +354,9 @@ func (am *DefaultAccountManager) GetNetworkMap(peerPubKey string) (*NetworkMap,
|
||||
}
|
||||
|
||||
// GetPeerNetwork returns the Network for a given peer
|
||||
func (am *DefaultAccountManager) GetPeerNetwork(peerPubKey string) (*Network, error) {
|
||||
func (am *DefaultAccountManager) GetPeerNetwork(peerID string) (*Network, error) {
|
||||
|
||||
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
|
||||
account, err := am.Store.GetAccountByPeerID(peerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -357,7 +365,7 @@ func (am *DefaultAccountManager) GetPeerNetwork(peerPubKey string) (*Network, er
|
||||
}
|
||||
|
||||
// AddPeer adds a new peer to the Store.
|
||||
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err wit ha code codes.Unauthenticated
|
||||
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err with a code codes.Unauthenticated
|
||||
// will be returned, meaning the key is invalid
|
||||
// If a User ID is provided, it means that we passed the authentication using JWT, then we look for account by User ID and register the peer
|
||||
// to it. We also add the User ID to the peer metadata to identify registrant.
|
||||
@ -428,6 +436,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
|
||||
}
|
||||
|
||||
newPeer := &Peer{
|
||||
ID: xid.New().String(),
|
||||
Key: peer.Key,
|
||||
SetupKey: upperKey,
|
||||
IP: nextIp,
|
||||
@ -445,7 +454,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
group.Peers = append(group.Peers, newPeer.Key)
|
||||
group.Peers = append(group.Peers, newPeer.ID)
|
||||
|
||||
var groupsToAdd []string
|
||||
if addedByUser {
|
||||
@ -463,19 +472,19 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
|
||||
if len(groupsToAdd) > 0 {
|
||||
for _, s := range groupsToAdd {
|
||||
if g, ok := account.Groups[s]; ok && g.Name != "All" {
|
||||
g.Peers = append(g.Peers, newPeer.Key)
|
||||
g.Peers = append(g.Peers, newPeer.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
account.Peers[newPeer.Key] = newPeer
|
||||
account.Peers[newPeer.ID] = newPeer
|
||||
account.Network.IncSerial()
|
||||
err = am.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opEvent.TargetID = newPeer.IP.String()
|
||||
opEvent.TargetID = newPeer.ID
|
||||
opEvent.Meta = newPeer.EventMeta(am.GetDNSDomain())
|
||||
am.storeEvent(opEvent.InitiatorID, opEvent.TargetID, opEvent.AccountID, opEvent.Activity, opEvent.Meta)
|
||||
|
||||
@ -483,14 +492,14 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
|
||||
}
|
||||
|
||||
// UpdatePeerSSHKey updates peer's public SSH key
|
||||
func (am *DefaultAccountManager) UpdatePeerSSHKey(peerPubKey string, sshKey string) error {
|
||||
func (am *DefaultAccountManager) UpdatePeerSSHKey(peerID string, sshKey string) error {
|
||||
|
||||
if sshKey == "" {
|
||||
log.Debugf("empty SSH key provided for peer %s, skipping update", peerPubKey)
|
||||
log.Debugf("empty SSH key provided for peer %s, skipping update", peerID)
|
||||
return nil
|
||||
}
|
||||
|
||||
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
|
||||
account, err := am.Store.GetAccountByPeerID(peerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -504,13 +513,13 @@ func (am *DefaultAccountManager) UpdatePeerSSHKey(peerPubKey string, sshKey stri
|
||||
return err
|
||||
}
|
||||
|
||||
peer, err := account.FindPeerByPubKey(peerPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
peer := account.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
return status.Errorf(status.NotFound, "peer with ID %s not found", peerID)
|
||||
}
|
||||
|
||||
if peer.SSHKey == sshKey {
|
||||
log.Debugf("same SSH key provided for peer %s, skipping update", peerPubKey)
|
||||
log.Debugf("same SSH key provided for peer %s, skipping update", peerID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -527,9 +536,9 @@ func (am *DefaultAccountManager) UpdatePeerSSHKey(peerPubKey string, sshKey stri
|
||||
}
|
||||
|
||||
// UpdatePeerMeta updates peer's system metadata
|
||||
func (am *DefaultAccountManager) UpdatePeerMeta(peerPubKey string, meta PeerSystemMeta) error {
|
||||
func (am *DefaultAccountManager) UpdatePeerMeta(peerID string, meta PeerSystemMeta) error {
|
||||
|
||||
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
|
||||
account, err := am.Store.GetAccountByPeerID(peerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -537,9 +546,9 @@ func (am *DefaultAccountManager) UpdatePeerMeta(peerPubKey string, meta PeerSyst
|
||||
unlock := am.Store.AcquireAccountLock(account.Id)
|
||||
defer unlock()
|
||||
|
||||
peer, err := account.FindPeerByPubKey(peerPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
peer := account.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
return status.Errorf(status.NotFound, "peer with ID %s not found", peerID)
|
||||
}
|
||||
|
||||
// Avoid overwriting UIVersion if the update was triggered sole by the CLI client
|
||||
@ -558,9 +567,9 @@ func (am *DefaultAccountManager) UpdatePeerMeta(peerPubKey string, meta PeerSyst
|
||||
}
|
||||
|
||||
// getPeersByACL returns all peers that given peer has access to.
|
||||
func (a *Account) getPeersByACL(peerPubKey string) []*Peer {
|
||||
func (a *Account) getPeersByACL(peerID string) []*Peer {
|
||||
var peers []*Peer
|
||||
srcRules, dstRules := a.GetPeerRules(peerPubKey)
|
||||
srcRules, dstRules := a.GetPeerRules(peerID)
|
||||
|
||||
groups := map[string]*Group{}
|
||||
for _, r := range srcRules {
|
||||
@ -603,8 +612,8 @@ func (a *Account) getPeersByACL(peerPubKey string) []*Peer {
|
||||
continue
|
||||
}
|
||||
// exclude original peer
|
||||
if _, ok := peersSet[peer.Key]; peer.Key != peerPubKey && !ok {
|
||||
peersSet[peer.Key] = struct{}{}
|
||||
if _, ok := peersSet[peer.ID]; peer.ID != peerID && !ok {
|
||||
peersSet[peer.ID] = struct{}{}
|
||||
peers = append(peers, peer.Copy())
|
||||
}
|
||||
}
|
||||
@ -619,13 +628,13 @@ func (am *DefaultAccountManager) updateAccountPeers(account *Account) error {
|
||||
peers := account.GetPeers()
|
||||
|
||||
for _, peer := range peers {
|
||||
remotePeerNetworkMap, err := am.GetNetworkMap(peer.Key)
|
||||
remotePeerNetworkMap, err := am.GetNetworkMap(peer.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
update := toSyncResponse(nil, peer, nil, remotePeerNetworkMap, am.GetDNSDomain())
|
||||
err = am.peersUpdateManager.SendUpdate(peer.Key, &UpdateMessage{Update: update})
|
||||
err = am.peersUpdateManager.SendUpdate(peer.ID, &UpdateMessage{Update: update})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func TestAccountManager_GetNetworkMap(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
peer1, err := manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
Key: peerKey1.PublicKey().String(),
|
||||
Meta: PeerSystemMeta{},
|
||||
Name: "test-peer-2",
|
||||
@ -61,7 +61,7 @@ func TestAccountManager_GetNetworkMap(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
networkMap, err := manager.GetNetworkMap(peerKey1.PublicKey().String())
|
||||
networkMap, err := manager.GetNetworkMap(peer1.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
@ -107,7 +107,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
peer1, err := manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
Key: peerKey1.PublicKey().String(),
|
||||
Meta: PeerSystemMeta{},
|
||||
Name: "test-peer-2",
|
||||
@ -123,7 +123,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
_, err = manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
peer2, err := manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
Key: peerKey2.PublicKey().String(),
|
||||
Meta: PeerSystemMeta{},
|
||||
Name: "test-peer-2",
|
||||
@ -156,8 +156,8 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
group1.Name = "src"
|
||||
group2.Name = "dst"
|
||||
rule.ID = xid.New().String()
|
||||
group1.Peers = append(group1.Peers, peerKey1.PublicKey().String())
|
||||
group2.Peers = append(group2.Peers, peerKey2.PublicKey().String())
|
||||
group1.Peers = append(group1.Peers, peer1.ID)
|
||||
group2.Peers = append(group2.Peers, peer2.ID)
|
||||
|
||||
err = manager.SaveGroup(account.Id, userID, &group1)
|
||||
if err != nil {
|
||||
@ -180,7 +180,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
networkMap1, err := manager.GetNetworkMap(peerKey1.PublicKey().String())
|
||||
networkMap1, err := manager.GetNetworkMap(peer1.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
@ -203,7 +203,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
networkMap2, err := manager.GetNetworkMap(peerKey2.PublicKey().String())
|
||||
networkMap2, err := manager.GetNetworkMap(peer2.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
@ -228,7 +228,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
networkMap1, err = manager.GetNetworkMap(peerKey1.PublicKey().String())
|
||||
networkMap1, err = manager.GetNetworkMap(peer1.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
@ -243,7 +243,7 @@ func TestAccountManager_GetNetworkMapWithRule(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
networkMap2, err = manager.GetNetworkMap(peerKey2.PublicKey().String())
|
||||
networkMap2, err = manager.GetNetworkMap(peer2.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
@ -281,7 +281,7 @@ func TestAccountManager_GetPeerNetwork(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
peer1, err := manager.AddPeer(setupKey.Key, "", &Peer{
|
||||
Key: peerKey1.PublicKey().String(),
|
||||
Meta: PeerSystemMeta{},
|
||||
Name: "test-peer-2",
|
||||
@ -308,7 +308,7 @@ func TestAccountManager_GetPeerNetwork(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
network, err := manager.GetPeerNetwork(peerKey1.PublicKey().String())
|
||||
network, err := manager.GetPeerNetwork(peer1.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
|
@ -91,9 +91,9 @@ func (am *DefaultAccountManager) GetRoute(accountID, routeID, userID string) (*r
|
||||
}
|
||||
|
||||
// checkPrefixPeerExists checks the combination of prefix and peer id, if it exists returns an error, otherwise returns nil
|
||||
func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, prefix netip.Prefix) error {
|
||||
func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peerID string, prefix netip.Prefix) error {
|
||||
|
||||
if peer == "" {
|
||||
if peerID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -111,15 +111,15 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, p
|
||||
return status.Errorf(status.InvalidArgument, "failed to parse prefix %s", prefix.String())
|
||||
}
|
||||
for _, prefixRoute := range routesWithPrefix {
|
||||
if prefixRoute.Peer == peer {
|
||||
return status.Errorf(status.AlreadyExists, "failed a route with prefix %s and peer already exist", prefix.String())
|
||||
if prefixRoute.Peer == peerID {
|
||||
return status.Errorf(status.AlreadyExists, "failed to add route with prefix %s - peer already has this route", prefix.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateRoute creates and saves a new route
|
||||
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
|
||||
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerID, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
|
||||
unlock := am.Store.AcquireAccountLock(accountID)
|
||||
defer unlock()
|
||||
|
||||
@ -128,13 +128,11 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerIP,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peerKey := ""
|
||||
if peerIP != "" {
|
||||
peer := account.GetPeerByIP(peerIP)
|
||||
if peerID != "" {
|
||||
peer := account.GetPeer(peerID)
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.NotFound, "peer %s not found", peerIP)
|
||||
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", peerID)
|
||||
}
|
||||
peerKey = peer.Key
|
||||
}
|
||||
|
||||
var newRoute route.Route
|
||||
@ -142,7 +140,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerIP,
|
||||
if err != nil {
|
||||
return nil, status.Errorf(status.InvalidArgument, "failed to parse IP %s", network)
|
||||
}
|
||||
err = am.checkPrefixPeerExists(accountID, peerKey, newPrefix)
|
||||
err = am.checkPrefixPeerExists(accountID, peerID, newPrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -160,7 +158,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerIP,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newRoute.Peer = peerKey
|
||||
newRoute.Peer = peerID
|
||||
newRoute.ID = xid.New().String()
|
||||
newRoute.Network = newPrefix
|
||||
newRoute.NetworkType = prefixType
|
||||
@ -220,9 +218,9 @@ func (am *DefaultAccountManager) SaveRoute(accountID, userID string, routeToSave
|
||||
}
|
||||
|
||||
if routeToSave.Peer != "" {
|
||||
_, peerExist := account.Peers[routeToSave.Peer]
|
||||
if !peerExist {
|
||||
return status.Errorf(status.InvalidArgument, "failed to find Peer %s", routeToSave.Peer)
|
||||
peer := account.GetPeer(routeToSave.Peer)
|
||||
if peer == nil {
|
||||
return status.Errorf(status.InvalidArgument, "peer with ID %s not found", routeToSave.Peer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,9 +236,14 @@ func (am *DefaultAccountManager) SaveRoute(accountID, userID string, routeToSave
|
||||
return err
|
||||
}
|
||||
|
||||
err = am.updateAccountPeers(account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
am.storeEvent(userID, routeToSave.ID, accountID, activity.RouteUpdated, routeToSave.EventMeta())
|
||||
|
||||
return am.updateAccountPeers(account)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateRoute updates existing route with set of operations
|
||||
@ -287,9 +290,9 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
|
||||
newRoute.NetworkType = prefixType
|
||||
case UpdateRoutePeer:
|
||||
if operation.Values[0] != "" {
|
||||
_, peerExist := account.Peers[operation.Values[0]]
|
||||
if !peerExist {
|
||||
return nil, status.Errorf(status.InvalidArgument, "failed to find Peer %s", operation.Values[0])
|
||||
peer := account.GetPeer(operation.Values[0])
|
||||
if peer == nil {
|
||||
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", operation.Values[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
const (
|
||||
peer1Key = "BhRPtynAAYRDy08+q4HTMsos8fs4plTP4NOSh7C1ry8="
|
||||
peer2Key = "/yF0+vCfv+mRR5k0dca0TrGdO/oiNeAI58gToZm5NyI="
|
||||
peer1ID = "peer-1-id"
|
||||
peer2ID = "peer-2-id"
|
||||
routeGroup1 = "routeGroup1"
|
||||
routeGroup2 = "routeGroup2"
|
||||
routeInvalidGroup1 = "routeInvalidGroup1"
|
||||
@ -23,7 +25,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
type input struct {
|
||||
network string
|
||||
netID string
|
||||
peer string
|
||||
peerKey string
|
||||
description string
|
||||
masquerade bool
|
||||
metric int
|
||||
@ -43,7 +45,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "happy",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -56,7 +58,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetworkType: route.IPv4Network,
|
||||
NetID: "happy",
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -69,7 +71,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/34",
|
||||
netID: "happy",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -84,7 +86,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "happy",
|
||||
peer: "notExistingPeer",
|
||||
peerKey: "notExistingPeer",
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -99,7 +101,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "happy",
|
||||
peer: "",
|
||||
peerKey: "",
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -124,7 +126,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
name: "Large Metric Should Fail",
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
netID: "happy",
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
@ -140,7 +142,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "happy",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
metric: 0,
|
||||
@ -154,7 +156,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
name: "Large NetID Should Fail",
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
netID: "12345678901234567890qwertyuiopqwertyuiop1",
|
||||
description: "super",
|
||||
masquerade: false,
|
||||
@ -170,7 +172,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -185,7 +187,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "NewId",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -200,7 +202,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "NewId",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -215,7 +217,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
inputArgs: input{
|
||||
network: "192.168.0.0/16",
|
||||
netID: "NewId",
|
||||
peer: peer1Key,
|
||||
peerKey: peer1ID,
|
||||
description: "",
|
||||
masquerade: false,
|
||||
metric: 9999,
|
||||
@ -238,18 +240,10 @@ func TestCreateRoute(t *testing.T) {
|
||||
t.Error("failed to init testing account")
|
||||
}
|
||||
|
||||
peerIP := "99.99.99.99"
|
||||
peer := account.Peers[testCase.inputArgs.peer]
|
||||
if testCase.inputArgs.peer == "" {
|
||||
peerIP = ""
|
||||
} else if peer != nil {
|
||||
peerIP = peer.IP.String()
|
||||
}
|
||||
|
||||
outRoute, err := am.CreateRoute(
|
||||
account.Id,
|
||||
testCase.inputArgs.network,
|
||||
peerIP,
|
||||
testCase.inputArgs.peerKey,
|
||||
testCase.inputArgs.description,
|
||||
testCase.inputArgs.netID,
|
||||
testCase.inputArgs.masquerade,
|
||||
@ -278,7 +272,7 @@ func TestCreateRoute(t *testing.T) {
|
||||
|
||||
func TestSaveRoute(t *testing.T) {
|
||||
|
||||
validPeer := peer2Key
|
||||
validPeer := peer2ID
|
||||
invalidPeer := "nonExisting"
|
||||
validPrefix := netip.MustParsePrefix("192.168.0.0/24")
|
||||
invalidPrefix, _ := netip.ParsePrefix("192.168.0.0/34")
|
||||
@ -306,7 +300,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -339,7 +333,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -356,7 +350,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -373,7 +367,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -390,7 +384,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: invalidNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -407,7 +401,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -424,7 +418,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -441,7 +435,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -458,7 +452,7 @@ func TestSaveRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: validNetID,
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -495,7 +489,6 @@ func TestSaveRoute(t *testing.T) {
|
||||
if testCase.newPeer != nil {
|
||||
routeToSave.Peer = *testCase.newPeer
|
||||
}
|
||||
|
||||
if testCase.newMetric != nil {
|
||||
routeToSave.Metric = *testCase.newMetric
|
||||
}
|
||||
@ -541,7 +534,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: "superRoute",
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -563,7 +556,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
operations: []RouteUpdateOperation{
|
||||
{
|
||||
Type: UpdateRoutePeer,
|
||||
Values: []string{peer2Key},
|
||||
Values: []string{peer2ID},
|
||||
},
|
||||
},
|
||||
errFunc: require.NoError,
|
||||
@ -573,7 +566,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: "superRoute",
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer2Key,
|
||||
Peer: peer2ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -595,7 +588,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Type: UpdateRoutePeer,
|
||||
Values: []string{peer2Key},
|
||||
Values: []string{peer2ID},
|
||||
},
|
||||
{
|
||||
Type: UpdateRouteMetric,
|
||||
@ -625,7 +618,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/24"),
|
||||
NetID: "megaRoute",
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer2Key,
|
||||
Peer: peer2ID,
|
||||
Description: "great",
|
||||
Masquerade: true,
|
||||
Metric: 3030,
|
||||
@ -649,7 +642,7 @@ func TestUpdateRoute(t *testing.T) {
|
||||
operations: []RouteUpdateOperation{
|
||||
{
|
||||
Type: UpdateRoutePeer,
|
||||
Values: []string{peer2Key, peer1Key},
|
||||
Values: []string{peer2ID, peer1ID},
|
||||
},
|
||||
},
|
||||
errFunc: require.Error,
|
||||
@ -847,7 +840,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
||||
Network: netip.MustParsePrefix("192.168.0.0/16"),
|
||||
NetID: "superNet",
|
||||
NetworkType: route.IPv4Network,
|
||||
Peer: peer1Key,
|
||||
Peer: peer1ID,
|
||||
Description: "super",
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
@ -865,39 +858,42 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
||||
t.Error("failed to init testing account")
|
||||
}
|
||||
|
||||
newAccountRoutes, err := am.GetNetworkMap(peer1Key)
|
||||
newAccountRoutes, err := am.GetNetworkMap(peer1ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, newAccountRoutes.Routes, 0, "new accounts should have no routes")
|
||||
peer := account.Peers[baseRoute.Peer]
|
||||
|
||||
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), peer.IP.String(),
|
||||
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), peer1ID,
|
||||
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, baseRoute.Groups, false,
|
||||
userID)
|
||||
require.NoError(t, err)
|
||||
|
||||
noDisabledRoutes, err := am.GetNetworkMap(peer1Key)
|
||||
noDisabledRoutes, err := am.GetNetworkMap(peer1ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, noDisabledRoutes.Routes, 0, "no routes for disabled routes")
|
||||
|
||||
enabledRoute := createdRoute.Copy()
|
||||
enabledRoute.Enabled = true
|
||||
|
||||
// network map contains route.Route objects that have Route.Peer field filled with Peer.Key instead of Peer.ID
|
||||
expectedRoute := enabledRoute.Copy()
|
||||
expectedRoute.Peer = peer1Key
|
||||
|
||||
err = am.SaveRoute(account.Id, userID, enabledRoute)
|
||||
require.NoError(t, err)
|
||||
|
||||
peer1Routes, err := am.GetNetworkMap(peer1Key)
|
||||
peer1Routes, err := am.GetNetworkMap(peer1ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer1Routes.Routes, 1, "we should receive one route for peer1")
|
||||
require.True(t, enabledRoute.IsEqual(peer1Routes.Routes[0]), "received route should be equal")
|
||||
require.True(t, expectedRoute.IsEqual(peer1Routes.Routes[0]), "received route should be equal")
|
||||
|
||||
peer2Routes, err := am.GetNetworkMap(peer2Key)
|
||||
peer2Routes, err := am.GetNetworkMap(peer2ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer2Routes.Routes, 0, "no routes for peers not in the distribution group")
|
||||
|
||||
err = am.GroupAddPeer(account.Id, routeGroup1, peer2Key)
|
||||
err = am.GroupAddPeer(account.Id, routeGroup1, peer2ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
peer2Routes, err = am.GetNetworkMap(peer2Key)
|
||||
peer2Routes, err = am.GetNetworkMap(peer2ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer2Routes.Routes, 1, "we should receive one route")
|
||||
require.True(t, peer1Routes.Routes[0].IsEqual(peer2Routes.Routes[0]), "routes should be the same for peers in the same group")
|
||||
@ -905,7 +901,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
||||
newGroup := &Group{
|
||||
ID: xid.New().String(),
|
||||
Name: "peer1 group",
|
||||
Peers: []string{peer1Key},
|
||||
Peers: []string{peer1ID},
|
||||
}
|
||||
err = am.SaveGroup(account.Id, userID, newGroup)
|
||||
require.NoError(t, err)
|
||||
@ -926,18 +922,18 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
|
||||
err = am.DeleteRule(account.Id, defaultRule.ID, userID)
|
||||
require.NoError(t, err)
|
||||
|
||||
peer1GroupRoutes, err := am.GetNetworkMap(peer1Key)
|
||||
peer1GroupRoutes, err := am.GetNetworkMap(peer1ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer1GroupRoutes.Routes, 1, "we should receive one route for peer1")
|
||||
|
||||
peer2GroupRoutes, err := am.GetNetworkMap(peer2Key)
|
||||
peer2GroupRoutes, err := am.GetNetworkMap(peer2ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer2GroupRoutes.Routes, 0, "we should not receive routes for peer2")
|
||||
|
||||
err = am.DeleteRoute(account.Id, enabledRoute.ID, userID)
|
||||
require.NoError(t, err)
|
||||
|
||||
peer1DeletedRoute, err := am.GetNetworkMap(peer1Key)
|
||||
peer1DeletedRoute, err := am.GetNetworkMap(peer1ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, peer1DeletedRoute.Routes, 0, "we should receive one route for peer1")
|
||||
|
||||
@ -964,9 +960,27 @@ func createRouterStore(t *testing.T) (Store, error) {
|
||||
|
||||
func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) {
|
||||
|
||||
accountID := "testingAcc"
|
||||
domain := "example.com"
|
||||
|
||||
account := newAccountWithId(accountID, userID, domain)
|
||||
err := am.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ips := account.getTakenIPs()
|
||||
peer1IP, err := AllocatePeerIP(account.Network.Net, ips)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer1 := &Peer{
|
||||
Key: peer1Key,
|
||||
Name: "test-host1@netbird.io",
|
||||
IP: peer1IP,
|
||||
ID: peer1ID,
|
||||
Key: peer1Key,
|
||||
Name: "test-host1@netbird.io",
|
||||
UserID: userID,
|
||||
Meta: PeerSystemMeta{
|
||||
Hostname: "test-host1@netbird.io",
|
||||
GoOS: "linux",
|
||||
@ -978,9 +992,20 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
|
||||
UIVersion: "development",
|
||||
},
|
||||
}
|
||||
account.Peers[peer1.ID] = peer1
|
||||
|
||||
ips = account.getTakenIPs()
|
||||
peer2IP, err := AllocatePeerIP(account.Network.Net, ips)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer2 := &Peer{
|
||||
Key: peer2Key,
|
||||
Name: "test-host2@netbird.io",
|
||||
IP: peer2IP,
|
||||
ID: peer2ID,
|
||||
Key: peer2Key,
|
||||
Name: "test-host2@netbird.io",
|
||||
UserID: userID,
|
||||
Meta: PeerSystemMeta{
|
||||
Hostname: "test-host2@netbird.io",
|
||||
GoOS: "linux",
|
||||
@ -992,28 +1017,29 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
|
||||
UIVersion: "development",
|
||||
},
|
||||
}
|
||||
account.Peers[peer2.ID] = peer2
|
||||
|
||||
accountID := "testingAcc"
|
||||
domain := "example.com"
|
||||
|
||||
account := newAccountWithId(accountID, userID, domain)
|
||||
err := am.Store.SaveAccount(account)
|
||||
err = am.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupAll, err := account.GetGroupAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = am.GroupAddPeer(accountID, groupAll.ID, peer1ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = am.GroupAddPeer(accountID, groupAll.ID, peer2ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = am.AddPeer("", userID, peer1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = am.AddPeer("", userID, peer2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newGroup := &Group{
|
||||
ID: routeGroup1,
|
||||
Name: routeGroup1,
|
||||
Peers: []string{peer1Key},
|
||||
Peers: []string{peer1.ID},
|
||||
}
|
||||
err = am.SaveGroup(accountID, userID, newGroup)
|
||||
if err != nil {
|
||||
@ -1023,7 +1049,7 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, er
|
||||
newGroup = &Group{
|
||||
ID: routeGroup2,
|
||||
Name: routeGroup2,
|
||||
Peers: []string{peer1Key},
|
||||
Peers: []string{peer2.ID},
|
||||
}
|
||||
|
||||
err = am.SaveGroup(accountID, userID, newGroup)
|
||||
|
@ -5,6 +5,7 @@ type Store interface {
|
||||
GetAccount(accountID string) (*Account, error)
|
||||
GetAccountByUser(userID string) (*Account, error)
|
||||
GetAccountByPeerPubKey(peerKey string) (*Account, error)
|
||||
GetAccountByPeerID(peerID string) (*Account, error)
|
||||
GetAccountBySetupKey(setupKey string) (*Account, error) //todo use key hash later
|
||||
GetAccountByPrivateDomain(domain string) (*Account, error)
|
||||
SaveAccount(account *Account) error
|
||||
@ -14,7 +15,7 @@ type Store interface {
|
||||
AcquireAccountLock(accountID string) func()
|
||||
// AcquireGlobalLock should attempt to acquire a global lock and return a function that releases the lock
|
||||
AcquireGlobalLock() func()
|
||||
SavePeerStatus(accountID, peerKey string, status PeerStatus) error
|
||||
SavePeerStatus(accountID, peerID string, status PeerStatus) error
|
||||
// Close should close the store persisting all unsaved data.
|
||||
Close() error
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//TURNCredentialsManager used to manage TURN credentials
|
||||
// TURNCredentialsManager used to manage TURN credentials
|
||||
type TURNCredentialsManager interface {
|
||||
GenerateCredentials() TURNCredentials
|
||||
SetupRefresh(peerKey string)
|
||||
CancelRefresh(peerKey string)
|
||||
}
|
||||
|
||||
//TimeBasedAuthSecretsManager generates credentials with TTL and using pre-shared secret known to TURN server
|
||||
// TimeBasedAuthSecretsManager generates credentials with TTL and using pre-shared secret known to TURN server
|
||||
type TimeBasedAuthSecretsManager struct {
|
||||
mux sync.Mutex
|
||||
config *TURNConfig
|
||||
@ -40,7 +40,7 @@ func NewTimeBasedAuthSecretsManager(updateManager *PeersUpdateManager, config *T
|
||||
}
|
||||
}
|
||||
|
||||
//GenerateCredentials generates new time-based secret credentials - basically username is a unix timestamp and password is a HMAC hash of a timestamp with a preshared TURN secret
|
||||
// GenerateCredentials generates new time-based secret credentials - basically username is a unix timestamp and password is a HMAC hash of a timestamp with a preshared TURN secret
|
||||
func (m *TimeBasedAuthSecretsManager) GenerateCredentials() TURNCredentials {
|
||||
mac := hmac.New(sha1.New, []byte(m.config.Secret))
|
||||
|
||||
@ -70,22 +70,22 @@ func (m *TimeBasedAuthSecretsManager) cancel(peerKey string) {
|
||||
}
|
||||
}
|
||||
|
||||
//CancelRefresh cancels scheduled peer credentials refresh
|
||||
// CancelRefresh cancels scheduled peer credentials refresh
|
||||
func (m *TimeBasedAuthSecretsManager) CancelRefresh(peerKey string) {
|
||||
m.mux.Lock()
|
||||
defer m.mux.Unlock()
|
||||
m.cancel(peerKey)
|
||||
}
|
||||
|
||||
//SetupRefresh starts peer credentials refresh. Since credentials are expiring (TTL) it is necessary to always generate them and send to the peer.
|
||||
//A goroutine is created and put into TimeBasedAuthSecretsManager.cancelMap. This routine should be cancelled if peer is gone.
|
||||
func (m *TimeBasedAuthSecretsManager) SetupRefresh(peerKey string) {
|
||||
// SetupRefresh starts peer credentials refresh. Since credentials are expiring (TTL) it is necessary to always generate them and send to the peer.
|
||||
// A goroutine is created and put into TimeBasedAuthSecretsManager.cancelMap. This routine should be cancelled if peer is gone.
|
||||
func (m *TimeBasedAuthSecretsManager) SetupRefresh(peerID string) {
|
||||
m.mux.Lock()
|
||||
defer m.mux.Unlock()
|
||||
m.cancel(peerKey)
|
||||
m.cancel(peerID)
|
||||
cancel := make(chan struct{}, 1)
|
||||
m.cancelMap[peerKey] = cancel
|
||||
log.Debugf("starting turn refresh for %s", peerKey)
|
||||
m.cancelMap[peerID] = cancel
|
||||
log.Debugf("starting turn refresh for %s", peerID)
|
||||
|
||||
go func() {
|
||||
//we don't want to regenerate credentials right on expiration, so we do it slightly before (at 3/4 of TTL)
|
||||
@ -94,7 +94,7 @@ func (m *TimeBasedAuthSecretsManager) SetupRefresh(peerKey string) {
|
||||
for {
|
||||
select {
|
||||
case <-cancel:
|
||||
log.Debugf("stopping turn refresh for %s", peerKey)
|
||||
log.Debugf("stopping turn refresh for %s", peerID)
|
||||
return
|
||||
case <-ticker.C:
|
||||
c := m.GenerateCredentials()
|
||||
@ -115,9 +115,9 @@ func (m *TimeBasedAuthSecretsManager) SetupRefresh(peerKey string) {
|
||||
Turns: turns,
|
||||
},
|
||||
}
|
||||
err := m.updateManager.SendUpdate(peerKey, &UpdateMessage{Update: update})
|
||||
err := m.updateManager.SendUpdate(peerID, &UpdateMessage{Update: update})
|
||||
if err != nil {
|
||||
log.Errorf("error while sending TURN update to peer %s %v", peerKey, err)
|
||||
log.Errorf("error while sending TURN update to peer %s %v", peerID, err)
|
||||
// todo maybe continue trying?
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ type UpdateMessage struct {
|
||||
}
|
||||
|
||||
type PeersUpdateManager struct {
|
||||
// peerChannels is an update channel indexed by Peer.ID
|
||||
peerChannels map[string]chan *UpdateMessage
|
||||
channelsMux *sync.Mutex
|
||||
}
|
||||
@ -26,49 +27,49 @@ func NewPeersUpdateManager() *PeersUpdateManager {
|
||||
}
|
||||
|
||||
// SendUpdate sends update message to the peer's channel
|
||||
func (p *PeersUpdateManager) SendUpdate(peer string, update *UpdateMessage) error {
|
||||
func (p *PeersUpdateManager) SendUpdate(peerID string, update *UpdateMessage) error {
|
||||
p.channelsMux.Lock()
|
||||
defer p.channelsMux.Unlock()
|
||||
if channel, ok := p.peerChannels[peer]; ok {
|
||||
if channel, ok := p.peerChannels[peerID]; ok {
|
||||
select {
|
||||
case channel <- update:
|
||||
log.Infof("update was sent to channel for peer %s", peer)
|
||||
log.Infof("update was sent to channel for peer %s", peerID)
|
||||
default:
|
||||
log.Warnf("channel for peer %s is %d full", peer, len(channel))
|
||||
log.Warnf("channel for peer %s is %d full", peerID, len(channel))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
log.Debugf("peer %s has no channel", peer)
|
||||
log.Debugf("peer %s has no channel", peerID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateChannel creates a go channel for a given peer used to deliver updates relevant to the peer.
|
||||
func (p *PeersUpdateManager) CreateChannel(peerKey string) chan *UpdateMessage {
|
||||
func (p *PeersUpdateManager) CreateChannel(peerID string) chan *UpdateMessage {
|
||||
p.channelsMux.Lock()
|
||||
defer p.channelsMux.Unlock()
|
||||
|
||||
if channel, ok := p.peerChannels[peerKey]; ok {
|
||||
delete(p.peerChannels, peerKey)
|
||||
if channel, ok := p.peerChannels[peerID]; ok {
|
||||
delete(p.peerChannels, peerID)
|
||||
close(channel)
|
||||
}
|
||||
//mbragin: todo shouldn't it be more? or configurable?
|
||||
channel := make(chan *UpdateMessage, channelBufferSize)
|
||||
p.peerChannels[peerKey] = channel
|
||||
p.peerChannels[peerID] = channel
|
||||
|
||||
log.Debugf("opened updates channel for a peer %s", peerKey)
|
||||
log.Debugf("opened updates channel for a peer %s", peerID)
|
||||
return channel
|
||||
}
|
||||
|
||||
// CloseChannel closes updates channel of a given peer
|
||||
func (p *PeersUpdateManager) CloseChannel(peerKey string) {
|
||||
func (p *PeersUpdateManager) CloseChannel(peerID string) {
|
||||
p.channelsMux.Lock()
|
||||
defer p.channelsMux.Unlock()
|
||||
if channel, ok := p.peerChannels[peerKey]; ok {
|
||||
delete(p.peerChannels, peerKey)
|
||||
if channel, ok := p.peerChannels[peerID]; ok {
|
||||
delete(p.peerChannels, peerID)
|
||||
close(channel)
|
||||
}
|
||||
|
||||
log.Debugf("closed updates channel of a peer %s", peerKey)
|
||||
log.Debugf("closed updates channel of a peer %s", peerID)
|
||||
}
|
||||
|
||||
// GetAllConnectedPeers returns a copy of the connected peers map
|
||||
@ -76,8 +77,8 @@ func (p *PeersUpdateManager) GetAllConnectedPeers() map[string]struct{} {
|
||||
p.channelsMux.Lock()
|
||||
defer p.channelsMux.Unlock()
|
||||
m := make(map[string]struct{})
|
||||
for key := range p.peerChannels {
|
||||
m[key] = struct{}{}
|
||||
for ID := range p.peerChannels {
|
||||
m[ID] = struct{}{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ type Route struct {
|
||||
|
||||
// EventMeta returns activity event meta related to the route
|
||||
func (r *Route) EventMeta() map[string]any {
|
||||
return map[string]any{"name": r.NetID, "network_range": r.Network.String()}
|
||||
return map[string]any{"name": r.NetID, "network_range": r.Network.String(), "peer_id": r.Peer}
|
||||
}
|
||||
|
||||
// Copy copies a route object
|
||||
|
Loading…
Reference in New Issue
Block a user