Simplified Store Interface (#545)

This PR simplifies Store and FileStore
by keeping just the Get and Save account methods.

The AccountManager operates mostly around
a single account, so it makes sense to fetch
the whole account object from the store.
This commit is contained in:
Misha Bragin
2022-11-07 12:10:56 +01:00
committed by GitHub
parent 4321b71984
commit d0c6d88971
17 changed files with 537 additions and 783 deletions

View File

@@ -68,17 +68,17 @@ func (p *Peer) Copy() *Peer {
}
}
// GetPeer returns a peer from a Store
func (am *DefaultAccountManager) GetPeer(peerKey string) (*Peer, error) {
// GetPeer looks up peer by its public WireGuard key
func (am *DefaultAccountManager) GetPeer(peerPubKey string) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
peer, err := am.Store.GetPeer(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return nil, err
}
return peer, nil
return account.FindPeerByPubKey(peerPubKey)
}
// GetPeers returns a list of peers under the given account filtering out peers that do not belong to a user if
@@ -109,24 +109,26 @@ func (am *DefaultAccountManager) GetPeers(accountID, userID string) ([]*Peer, er
}
// MarkPeerConnected marks peer as connected (true) or disconnected (false)
func (am *DefaultAccountManager) MarkPeerConnected(peerKey string, connected bool) error {
func (am *DefaultAccountManager) MarkPeerConnected(peerPubKey string, connected bool) error {
am.mux.Lock()
defer am.mux.Unlock()
peer, err := am.Store.GetPeer(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return err
}
account, err := am.Store.GetPeerAccount(peerKey)
peer, err := account.FindPeerByPubKey(peerPubKey)
if err != nil {
return err
}
peerCopy := peer.Copy()
peerCopy.Status.LastSeen = time.Now()
peerCopy.Status.Connected = connected
err = am.Store.SavePeer(account.Id, peerCopy)
peer.Status.LastSeen = time.Now()
peer.Status.Connected = connected
account.UpdatePeer(peer)
err = am.Store.SaveAccount(account)
if err != nil {
return err
}
@@ -143,18 +145,20 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
return nil, status.Errorf(codes.NotFound, "account not found")
}
peer, err := am.Store.GetPeer(update.Key)
//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
}
peerCopy := peer.Copy()
if peer.Name != "" {
peerCopy.Name = update.Name
peer.Name = update.Name
}
peerCopy.SSHEnabled = update.SSHEnabled
peer.SSHEnabled = update.SSHEnabled
err = am.Store.SavePeer(accountID, peerCopy)
account.UpdatePeer(peer)
err = am.Store.SaveAccount(account)
if err != nil {
return nil, err
}
@@ -164,66 +168,32 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
return nil, err
}
return peerCopy, nil
return peer, nil
}
// RenamePeer changes peer's name
func (am *DefaultAccountManager) RenamePeer(
accountId string,
peerKey string,
newName string,
) (*Peer, error) {
// DeletePeer removes peer from the account by its IP
func (am *DefaultAccountManager) DeletePeer(accountID string, peerPubKey string) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
peer, err := am.Store.GetPeer(peerKey)
if err != nil {
return nil, err
}
peerCopy := peer.Copy()
peerCopy.Name = newName
err = am.Store.SavePeer(accountId, peerCopy)
if err != nil {
return nil, err
}
return peerCopy, nil
}
// DeletePeer removes peer from the account by it's IP
func (am *DefaultAccountManager) DeletePeer(accountId string, peerKey string) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
account, err := am.Store.GetAccount(accountId)
account, err := am.Store.GetAccount(accountID)
if err != nil {
return nil, status.Errorf(codes.NotFound, "account not found")
}
// delete peer from groups
for _, g := range account.Groups {
for i, pk := range g.Peers {
if pk == peerKey {
g.Peers = append(g.Peers[:i], g.Peers[i+1:]...)
break
}
}
}
peer, err := am.Store.DeletePeer(accountId, peerKey)
peer, err := account.FindPeerByPubKey(peerPubKey)
if err != nil {
return nil, err
}
account.Network.IncSerial()
account.DeletePeer(peerPubKey)
err = am.Store.SaveAccount(account)
if err != nil {
return nil, err
}
err = am.peersUpdateManager.SendUpdate(peerKey,
err = am.peersUpdateManager.SendUpdate(peerPubKey,
&UpdateMessage{
Update: &proto.SyncResponse{
// fill those field for backward compatibility
@@ -241,20 +211,21 @@ func (am *DefaultAccountManager) DeletePeer(accountId string, peerKey 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(peerKey)
am.peersUpdateManager.CloseChannel(peerPubKey)
return peer, nil
}
// GetPeerByIP returns peer by it's IP
func (am *DefaultAccountManager) GetPeerByIP(accountId string, peerIP string) (*Peer, error) {
// GetPeerByIP returns peer by its IP
func (am *DefaultAccountManager) GetPeerByIP(accountID string, peerIP string) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
account, err := am.Store.GetAccount(accountId)
account, err := am.Store.GetAccount(accountID)
if err != nil {
return nil, status.Errorf(codes.NotFound, "account not found")
}
@@ -269,17 +240,17 @@ 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(peerKey string) (*NetworkMap, error) {
func (am *DefaultAccountManager) GetNetworkMap(peerPubKey string) (*NetworkMap, error) {
am.mux.Lock()
defer am.mux.Unlock()
account, err := am.Store.GetPeerAccount(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerKey)
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerPubKey)
}
aclPeers := am.getPeersByACL(account, peerKey)
routesUpdate := am.getPeersRoutes(append(aclPeers, account.Peers[peerKey]))
aclPeers := am.getPeersByACL(account, peerPubKey)
routesUpdate := account.GetPeersRoutes(append(aclPeers, account.Peers[peerPubKey]))
return &NetworkMap{
Peers: aclPeers,
@@ -289,13 +260,13 @@ func (am *DefaultAccountManager) GetNetworkMap(peerKey string) (*NetworkMap, err
}
// GetPeerNetwork returns the Network for a given peer
func (am *DefaultAccountManager) GetPeerNetwork(peerKey string) (*Network, error) {
func (am *DefaultAccountManager) GetPeerNetwork(peerPubKey string) (*Network, error) {
am.mux.Lock()
defer am.mux.Unlock()
account, err := am.Store.GetPeerAccount(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return nil, status.Errorf(codes.Internal, "Invalid peer key %s", peerKey)
return nil, status.Errorf(codes.Internal, "invalid peer key %s", peerPubKey)
}
return account.Network.Copy(), err
@@ -308,11 +279,7 @@ func (am *DefaultAccountManager) GetPeerNetwork(peerKey string) (*Network, error
// to it. We also add the User ID to the peer metadata to identify registrant.
// Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused).
// The peer property is just a placeholder for the Peer properties to pass further
func (am *DefaultAccountManager) AddPeer(
setupKey string,
userID string,
peer *Peer,
) (*Peer, error) {
func (am *DefaultAccountManager) AddPeer(setupKey string, userID string, peer *Peer) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
@@ -353,7 +320,7 @@ func (am *DefaultAccountManager) AddPeer(
groupsToAdd = sk.AutoGroups
} else if len(userID) != 0 {
account, err = am.Store.GetUserAccount(userID)
account, err = am.Store.GetAccountByUser(userID)
if err != nil {
return nil, status.Errorf(codes.NotFound, "unable to register peer, unknown user with ID: %s", userID)
}
@@ -422,34 +389,34 @@ func (am *DefaultAccountManager) AddPeer(
}
// UpdatePeerSSHKey updates peer's public SSH key
func (am *DefaultAccountManager) UpdatePeerSSHKey(peerKey string, sshKey string) error {
func (am *DefaultAccountManager) UpdatePeerSSHKey(peerPubKey string, sshKey string) error {
am.mux.Lock()
defer am.mux.Unlock()
if sshKey == "" {
log.Debugf("empty SSH key provided for peer %s, skipping update", peerKey)
log.Debugf("empty SSH key provided for peer %s, skipping update", peerPubKey)
return nil
}
peer, err := am.Store.GetPeer(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return err
}
peer, err := account.FindPeerByPubKey(peerPubKey)
if err != nil {
return err
}
if peer.SSHKey == sshKey {
log.Debugf("same SSH key provided for peer %s, skipping update", peerKey)
log.Debugf("same SSH key provided for peer %s, skipping update", peerPubKey)
return nil
}
account, err := am.Store.GetPeerAccount(peerKey)
if err != nil {
return err
}
peer.SSHKey = sshKey
account.UpdatePeer(peer)
peerCopy := peer.Copy()
peerCopy.SSHKey = sshKey
err = am.Store.SavePeer(account.Id, peerCopy)
err = am.Store.SaveAccount(account)
if err != nil {
return err
}
@@ -459,29 +426,29 @@ func (am *DefaultAccountManager) UpdatePeerSSHKey(peerKey string, sshKey string)
}
// UpdatePeerMeta updates peer's system metadata
func (am *DefaultAccountManager) UpdatePeerMeta(peerKey string, meta PeerSystemMeta) error {
func (am *DefaultAccountManager) UpdatePeerMeta(peerPubKey string, meta PeerSystemMeta) error {
am.mux.Lock()
defer am.mux.Unlock()
peer, err := am.Store.GetPeer(peerKey)
account, err := am.Store.GetAccountByPeerPubKey(peerPubKey)
if err != nil {
return err
}
account, err := am.Store.GetPeerAccount(peerKey)
peer, err := account.FindPeerByPubKey(peerPubKey)
if err != nil {
return err
}
peerCopy := peer.Copy()
// Avoid overwriting UIVersion if the update was triggered sole by the CLI client
if meta.UIVersion == "" {
meta.UIVersion = peerCopy.Meta.UIVersion
meta.UIVersion = peer.Meta.UIVersion
}
peerCopy.Meta = meta
peer.Meta = meta
account.UpdatePeer(peer)
err = am.Store.SavePeer(account.Id, peerCopy)
err = am.Store.SaveAccount(account)
if err != nil {
return err
}
@@ -489,17 +456,9 @@ func (am *DefaultAccountManager) UpdatePeerMeta(peerKey string, meta PeerSystemM
}
// getPeersByACL returns all peers that given peer has access to.
func (am *DefaultAccountManager) getPeersByACL(account *Account, peerKey string) []*Peer {
func (am *DefaultAccountManager) getPeersByACL(account *Account, peerPubKey string) []*Peer {
var peers []*Peer
srcRules, err := am.Store.GetPeerSrcRules(account.Id, peerKey)
if err != nil {
srcRules = []*Rule{}
}
dstRules, err := am.Store.GetPeerDstRules(account.Id, peerKey)
if err != nil {
dstRules = []*Rule{}
}
srcRules, dstRules := account.GetPeerRules(peerPubKey)
groups := map[string]*Group{}
for _, r := range srcRules {
@@ -542,7 +501,7 @@ func (am *DefaultAccountManager) getPeersByACL(account *Account, peerKey string)
continue
}
// exclude original peer
if _, ok := peersSet[peer.Key]; peer.Key != peerKey && !ok {
if _, ok := peersSet[peer.Key]; peer.Key != peerPubKey && !ok {
peersSet[peer.Key] = struct{}{}
peers = append(peers, peer.Copy())
}
@@ -556,18 +515,14 @@ func (am *DefaultAccountManager) getPeersByACL(account *Account, peerKey string)
// Should be called when changes have to be synced to peers.
func (am *DefaultAccountManager) updateAccountPeers(account *Account) error {
// notify other peers of the change
peers, err := am.Store.GetAccountPeers(account.Id)
if err != nil {
return err
}
peers := account.GetPeers()
network := account.Network.Copy()
for _, peer := range peers {
aclPeers := am.getPeersByACL(account, peer.Key)
peersUpdate := toRemotePeerConfig(aclPeers)
routesUpdate := toProtocolRoutes(am.getPeersRoutes(append(aclPeers, peer)))
err = am.peersUpdateManager.SendUpdate(peer.Key,
routesUpdate := toProtocolRoutes(account.GetPeersRoutes(append(aclPeers, peer)))
err := am.peersUpdateManager.SendUpdate(peer.Key,
&UpdateMessage{
Update: &proto.SyncResponse{
// fill deprecated fields for backward compatibility