Refactor peer account updates for efficiency

This commit is contained in:
bcmmbaga 2024-07-20 12:37:25 +03:00
parent 713c0341be
commit 26f089e30d
No known key found for this signature in database
GPG Key ID: 7249A19D20613553

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"net" "net"
"slices"
"strings" "strings"
"time" "time"
@ -211,13 +212,19 @@ func (am *DefaultAccountManager) UpdatePeer(ctx context.Context, accountID, user
} }
account.UpdatePeer(peer) account.UpdatePeer(peer)
expired, _ := peer.LoginExpired(account.Settings.PeerLoginExpiration)
if expired && peer.LoginExpirationEnabled {
account.Network.IncSerial()
}
err = am.Store.SaveAccount(ctx, account) err = am.Store.SaveAccount(ctx, account)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if expired && peer.LoginExpirationEnabled {
am.updateAccountPeers(ctx, account) am.updateAccountPeers(ctx, account)
}
return peer, nil return peer, nil
} }
@ -289,7 +296,9 @@ func (am *DefaultAccountManager) DeletePeer(ctx context.Context, accountID, peer
return err return err
} }
if isPeerInActiveGroup(account, peerID) {
am.updateAccountPeers(ctx, account) am.updateAccountPeers(ctx, account)
}
return nil return nil
} }
@ -491,7 +500,12 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
} }
account.Peers[newPeer.ID] = newPeer account.Peers[newPeer.ID] = newPeer
updateAccountPeers := areGroupChangesAffectPeers(account, groupsToAdd)
if updateAccountPeers {
account.Network.IncSerial() account.Network.IncSerial()
}
err = am.Store.SaveAccount(ctx, account) err = am.Store.SaveAccount(ctx, account)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
@ -509,7 +523,9 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
am.StoreEvent(ctx, opEvent.InitiatorID, opEvent.TargetID, opEvent.AccountID, opEvent.Activity, opEvent.Meta) am.StoreEvent(ctx, opEvent.InitiatorID, opEvent.TargetID, opEvent.AccountID, opEvent.Activity, opEvent.Meta)
if updateAccountPeers {
am.updateAccountPeers(ctx, account) am.updateAccountPeers(ctx, account)
}
approvedPeersMap, err := am.GetValidatedPeers(account) approvedPeersMap, err := am.GetValidatedPeers(account)
if err != nil { if err != nil {
@ -537,33 +553,27 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync PeerSync, ac
return nil, nil, nil, status.Errorf(status.PermissionDenied, "peer login has expired, please log in once more") return nil, nil, nil, status.Errorf(status.PermissionDenied, "peer login has expired, please log in once more")
} }
peer, updated := updatePeerMeta(peer, sync.Meta, account)
if updated {
err = am.Store.SaveAccount(ctx, account)
if err != nil {
return nil, nil, nil, err
}
if sync.UpdateAccountPeers {
am.updateAccountPeers(ctx, account)
}
}
peerNotValid, isStatusChanged, err := am.integratedPeerValidator.IsNotValidPeer(ctx, account.Id, peer, account.GetPeerGroupsList(peer.ID), account.Settings.Extra) peerNotValid, isStatusChanged, err := am.integratedPeerValidator.IsNotValidPeer(ctx, account.Id, peer, account.GetPeerGroupsList(peer.ID), account.Settings.Extra)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
var postureChecks []*posture.Checks
if peerNotValid { if peerNotValid {
emptyMap := &NetworkMap{ emptyMap := &NetworkMap{
Network: account.Network.Copy(), Network: account.Network.Copy(),
} }
return peer, emptyMap, postureChecks, nil return peer, emptyMap, nil, nil
} }
if isStatusChanged { peer, peerMetaUpdated := updatePeerMeta(peer, sync.Meta, account)
if peerMetaUpdated {
err = am.Store.SaveAccount(ctx, account)
if err != nil {
return nil, nil, nil, err
}
}
if isStatusChanged || (peerMetaUpdated && sync.UpdateAccountPeers) {
am.updateAccountPeers(ctx, account) am.updateAccountPeers(ctx, account)
} }
@ -571,7 +581,7 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync PeerSync, ac
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
postureChecks = am.getPeerPostureChecks(account, peer) postureChecks := am.getPeerPostureChecks(account, peer)
return peer, account.GetPeerNetworkMap(ctx, peer.ID, am.dnsDomain, validPeersMap), postureChecks, nil return peer, account.GetPeerNetworkMap(ctx, peer.ID, am.dnsDomain, validPeersMap), postureChecks, nil
} }
@ -801,57 +811,9 @@ func (am *DefaultAccountManager) checkAndUpdatePeerSSHKey(ctx context.Context, p
return nil, err return nil, err
} }
// trigger network map update
am.updateAccountPeers(ctx, account)
return peer, nil return peer, nil
} }
// UpdatePeerSSHKey updates peer's public SSH key
func (am *DefaultAccountManager) UpdatePeerSSHKey(ctx context.Context, peerID string, sshKey string) error {
if sshKey == "" {
log.WithContext(ctx).Debugf("empty SSH key provided for peer %s, skipping update", peerID)
return nil
}
account, err := am.Store.GetAccountByPeerID(ctx, peerID)
if err != nil {
return err
}
unlock := am.Store.AcquireAccountWriteLock(ctx, account.Id)
defer unlock()
// ensure that we consider modification happened meanwhile (because we were outside the account lock when we fetched the account)
account, err = am.Store.GetAccount(ctx, account.Id)
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.WithContext(ctx).Debugf("same SSH key provided for peer %s, skipping update", peerID)
return nil
}
peer.SSHKey = sshKey
account.UpdatePeer(peer)
err = am.Store.SaveAccount(ctx, account)
if err != nil {
return err
}
// trigger network map update
am.updateAccountPeers(ctx, account)
return nil
}
// GetPeer for a given accountID, peerID and userID error if not found. // GetPeer for a given accountID, peerID and userID error if not found.
func (am *DefaultAccountManager) GetPeer(ctx context.Context, accountID, peerID, userID string) (*nbpeer.Peer, error) { func (am *DefaultAccountManager) GetPeer(ctx context.Context, accountID, peerID, userID string) (*nbpeer.Peer, error) {
unlock := am.Store.AcquireAccountWriteLock(ctx, accountID) unlock := am.Store.AcquireAccountWriteLock(ctx, accountID)
@ -935,3 +897,15 @@ func (am *DefaultAccountManager) updateAccountPeers(ctx context.Context, account
am.peersUpdateManager.SendUpdate(ctx, peer.ID, &UpdateMessage{Update: update}) am.peersUpdateManager.SendUpdate(ctx, peer.ID, &UpdateMessage{Update: update})
} }
} }
// IsPeerInActiveGroup checks if the given peer is part of a group that is used
// in an active DNS, route, or ACL configuration.
func isPeerInActiveGroup(account *Account, peerID string) bool {
peerGroupIDs := make([]string, 0)
for _, group := range account.Groups {
if slices.Contains(group.Peers, peerID) {
peerGroupIDs = append(peerGroupIDs, group.ID)
}
}
return areGroupChangesAffectPeers(account, peerGroupIDs)
}