mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-24 19:51:33 +02:00
[management] Add support for filtering peers by name and IP (#3279)
* add peers ip and name filters Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com> * add get peers filter Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com> * fix get account peers Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com> * Extend GetAccountPeers store to support filtering by name and IP Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com> * Fix get peers references Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com> --------- Signed-off-by: bcmmbaga <bethuelmbaga12@gmail.com>
This commit is contained in:
parent
1b011a2d85
commit
9ec61206c2
@ -86,7 +86,7 @@ type AccountManager interface {
|
|||||||
GetUserByID(ctx context.Context, id string) (*types.User, error)
|
GetUserByID(ctx context.Context, id string) (*types.User, error)
|
||||||
GetUser(ctx context.Context, claims jwtclaims.AuthorizationClaims) (*types.User, error)
|
GetUser(ctx context.Context, claims jwtclaims.AuthorizationClaims) (*types.User, error)
|
||||||
ListUsers(ctx context.Context, accountID string) ([]*types.User, error)
|
ListUsers(ctx context.Context, accountID string) ([]*types.User, error)
|
||||||
GetPeers(ctx context.Context, accountID, userID string) ([]*nbpeer.Peer, error)
|
GetPeers(ctx context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error)
|
||||||
MarkPeerConnected(ctx context.Context, peerKey string, connected bool, realIP net.IP, accountID string) error
|
MarkPeerConnected(ctx context.Context, peerKey string, connected bool, realIP net.IP, accountID string) error
|
||||||
DeletePeer(ctx context.Context, accountID, peerID, userID string) error
|
DeletePeer(ctx context.Context, accountID, peerID, userID string) error
|
||||||
UpdatePeer(ctx context.Context, accountID, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, error)
|
UpdatePeer(ctx context.Context, accountID, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, error)
|
||||||
|
@ -2183,6 +2183,17 @@ paths:
|
|||||||
summary: List all Peers
|
summary: List all Peers
|
||||||
description: Returns a list of all peers
|
description: Returns a list of all peers
|
||||||
tags: [ Peers ]
|
tags: [ Peers ]
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: name
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Filter peers by name
|
||||||
|
- in: query
|
||||||
|
name: ip
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Filter peers by IP address
|
||||||
security:
|
security:
|
||||||
- BearerAuth: [ ]
|
- BearerAuth: [ ]
|
||||||
- TokenAuth: [ ]
|
- TokenAuth: [ ]
|
||||||
|
@ -1580,6 +1580,15 @@ type UserRequest struct {
|
|||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetApiPeersParams defines parameters for GetApiPeers.
|
||||||
|
type GetApiPeersParams struct {
|
||||||
|
// Name Filter peers by name
|
||||||
|
Name *string `form:"name,omitempty" json:"name,omitempty"`
|
||||||
|
|
||||||
|
// Ip Filter peers by IP address
|
||||||
|
Ip *string `form:"ip,omitempty" json:"ip,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetApiPeersPeerIdIngressPortsParams defines parameters for GetApiPeersPeerIdIngressPorts.
|
// GetApiPeersPeerIdIngressPortsParams defines parameters for GetApiPeersPeerIdIngressPorts.
|
||||||
type GetApiPeersPeerIdIngressPortsParams struct {
|
type GetApiPeersPeerIdIngressPortsParams struct {
|
||||||
// Name Filters ingress port allocations by name
|
// Name Filters ingress port allocations by name
|
||||||
|
@ -60,7 +60,7 @@ func (h *handler) getAllGroups(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID)
|
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(r.Context(), err, w)
|
util.WriteError(r.Context(), err, w)
|
||||||
return
|
return
|
||||||
@ -154,7 +154,7 @@ func (h *handler) updateGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID)
|
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(r.Context(), err, w)
|
util.WriteError(r.Context(), err, w)
|
||||||
return
|
return
|
||||||
@ -213,7 +213,7 @@ func (h *handler) createGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID)
|
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(r.Context(), err, w)
|
util.WriteError(r.Context(), err, w)
|
||||||
return
|
return
|
||||||
@ -272,7 +272,7 @@ func (h *handler) getGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID)
|
accountPeers, err := h.accountManager.GetPeers(r.Context(), accountID, userID, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(r.Context(), err, w)
|
util.WriteError(r.Context(), err, w)
|
||||||
return
|
return
|
||||||
|
@ -69,7 +69,7 @@ func initGroupTestData(initGroups ...*types.Group) *handler {
|
|||||||
|
|
||||||
return nil, fmt.Errorf("unknown group name")
|
return nil, fmt.Errorf("unknown group name")
|
||||||
},
|
},
|
||||||
GetPeersFunc: func(ctx context.Context, accountID, userID string) ([]*nbpeer.Peer, error) {
|
GetPeersFunc: func(ctx context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error) {
|
||||||
return maps.Values(TestPeers), nil
|
return maps.Values(TestPeers), nil
|
||||||
},
|
},
|
||||||
DeleteGroupFunc: func(_ context.Context, accountID, userId, groupID string) error {
|
DeleteGroupFunc: func(_ context.Context, accountID, userId, groupID string) error {
|
||||||
|
@ -186,7 +186,10 @@ func (h *Handler) GetAllPeers(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
peers, err := h.accountManager.GetPeers(r.Context(), accountID, userID)
|
nameFilter := r.URL.Query().Get("name")
|
||||||
|
ipFilter := r.URL.Query().Get("ip")
|
||||||
|
|
||||||
|
peers, err := h.accountManager.GetPeers(r.Context(), accountID, userID, nameFilter, ipFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(r.Context(), err, w)
|
util.WriteError(r.Context(), err, w)
|
||||||
return
|
return
|
||||||
|
@ -125,7 +125,7 @@ func initTestMetaData(peers ...*nbpeer.Peer) *Handler {
|
|||||||
}
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
},
|
},
|
||||||
GetPeersFunc: func(_ context.Context, accountID, userID string) ([]*nbpeer.Peer, error) {
|
GetPeersFunc: func(_ context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error) {
|
||||||
return peers, nil
|
return peers, nil
|
||||||
},
|
},
|
||||||
GetPeerGroupsFunc: func(ctx context.Context, accountID, peerID string) ([]*types.Group, error) {
|
GetPeerGroupsFunc: func(ctx context.Context, accountID, peerID string) ([]*types.Group, error) {
|
||||||
|
@ -88,7 +88,7 @@ func (am *DefaultAccountManager) GetValidatedPeers(ctx context.Context, accountI
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
peers, err = transaction.GetAccountPeers(ctx, store.LockingStrengthShare, accountID)
|
peers, err = transaction.GetAccountPeers(ctx, store.LockingStrengthShare, accountID, "", "")
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -31,7 +31,7 @@ type MockAccountManager struct {
|
|||||||
GetAccountIDByUserIdFunc func(ctx context.Context, userId, domain string) (string, error)
|
GetAccountIDByUserIdFunc func(ctx context.Context, userId, domain string) (string, error)
|
||||||
GetUserFunc func(ctx context.Context, claims jwtclaims.AuthorizationClaims) (*types.User, error)
|
GetUserFunc func(ctx context.Context, claims jwtclaims.AuthorizationClaims) (*types.User, error)
|
||||||
ListUsersFunc func(ctx context.Context, accountID string) ([]*types.User, error)
|
ListUsersFunc func(ctx context.Context, accountID string) ([]*types.User, error)
|
||||||
GetPeersFunc func(ctx context.Context, accountID, userID string) ([]*nbpeer.Peer, error)
|
GetPeersFunc func(ctx context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error)
|
||||||
MarkPeerConnectedFunc func(ctx context.Context, peerKey string, connected bool, realIP net.IP) error
|
MarkPeerConnectedFunc func(ctx context.Context, peerKey string, connected bool, realIP net.IP) error
|
||||||
SyncAndMarkPeerFunc func(ctx context.Context, accountID string, peerPubKey string, meta nbpeer.PeerSystemMeta, realIP net.IP) (*nbpeer.Peer, *types.NetworkMap, []*posture.Checks, error)
|
SyncAndMarkPeerFunc func(ctx context.Context, accountID string, peerPubKey string, meta nbpeer.PeerSystemMeta, realIP net.IP) (*nbpeer.Peer, *types.NetworkMap, []*posture.Checks, error)
|
||||||
DeletePeerFunc func(ctx context.Context, accountID, peerKey, userID string) error
|
DeletePeerFunc func(ctx context.Context, accountID, peerKey, userID string) error
|
||||||
@ -628,9 +628,9 @@ func (am *MockAccountManager) CheckUserAccessByJWTGroups(ctx context.Context, cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPeers mocks GetPeers of the AccountManager interface
|
// GetPeers mocks GetPeers of the AccountManager interface
|
||||||
func (am *MockAccountManager) GetPeers(ctx context.Context, accountID, userID string) ([]*nbpeer.Peer, error) {
|
func (am *MockAccountManager) GetPeers(ctx context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error) {
|
||||||
if am.GetPeersFunc != nil {
|
if am.GetPeersFunc != nil {
|
||||||
return am.GetPeersFunc(ctx, accountID, userID)
|
return am.GetPeersFunc(ctx, accountID, userID, nameFilter, ipFilter)
|
||||||
}
|
}
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetPeers is not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetPeers is not implemented")
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ type PeerLogin struct {
|
|||||||
|
|
||||||
// GetPeers returns a list of peers under the given account filtering out peers that do not belong to a user if
|
// GetPeers returns a list of peers under the given account filtering out peers that do not belong to a user if
|
||||||
// the current user is not an admin.
|
// the current user is not an admin.
|
||||||
func (am *DefaultAccountManager) GetPeers(ctx context.Context, accountID, userID string) ([]*nbpeer.Peer, error) {
|
func (am *DefaultAccountManager) GetPeers(ctx context.Context, accountID, userID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error) {
|
||||||
user, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthShare, userID)
|
user, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthShare, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -76,7 +76,7 @@ func (am *DefaultAccountManager) GetPeers(ctx context.Context, accountID, userID
|
|||||||
return []*nbpeer.Peer{}, nil
|
return []*nbpeer.Peer{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
accountPeers, err := am.Store.GetAccountPeers(ctx, store.LockingStrengthShare, accountID)
|
accountPeers, err := am.Store.GetAccountPeers(ctx, store.LockingStrengthShare, accountID, nameFilter, ipFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -708,7 +708,7 @@ func TestDefaultAccountManager_GetPeers(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
peers, err := manager.GetPeers(context.Background(), accountID, someUser)
|
peers, err := manager.GetPeers(context.Background(), accountID, someUser, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
return
|
return
|
||||||
@ -914,7 +914,7 @@ func BenchmarkGetPeers(b *testing.B) {
|
|||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := manager.GetPeers(context.Background(), accountID, userID)
|
_, err := manager.GetPeers(context.Background(), accountID, userID, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("GetPeers failed: %v", err)
|
b.Fatalf("GetPeers failed: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -50,5 +50,5 @@ func (m *managerImpl) GetAllPeers(ctx context.Context, accountID, userID string)
|
|||||||
return nil, status.NewPermissionDeniedError()
|
return nil, status.NewPermissionDeniedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.store.GetAccountPeers(ctx, store.LockingStrengthShare, accountID)
|
return m.store.GetAccountPeers(ctx, store.LockingStrengthShare, accountID, "", "")
|
||||||
}
|
}
|
||||||
|
@ -1236,10 +1236,18 @@ func (s *SqlStore) GetPeerGroups(ctx context.Context, lockStrength LockingStreng
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountPeers retrieves peers for an account.
|
// GetAccountPeers retrieves peers for an account.
|
||||||
func (s *SqlStore) GetAccountPeers(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*nbpeer.Peer, error) {
|
func (s *SqlStore) GetAccountPeers(ctx context.Context, lockStrength LockingStrength, accountID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error) {
|
||||||
var peers []*nbpeer.Peer
|
var peers []*nbpeer.Peer
|
||||||
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Find(&peers, accountIDCondition, accountID)
|
query := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Where(accountIDCondition, accountID)
|
||||||
if err := result.Error; err != nil {
|
|
||||||
|
if nameFilter != "" {
|
||||||
|
query = query.Where("name LIKE ?", "%"+nameFilter+"%")
|
||||||
|
}
|
||||||
|
if ipFilter != "" {
|
||||||
|
query = query.Where("ip LIKE ?", "%"+ipFilter+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := query.Find(&peers).Error; err != nil {
|
||||||
log.WithContext(ctx).Errorf("failed to get peers from the store: %s", err)
|
log.WithContext(ctx).Errorf("failed to get peers from the store: %s", err)
|
||||||
return nil, status.Errorf(status.Internal, "failed to get peers from store")
|
return nil, status.Errorf(status.Internal, "failed to get peers from store")
|
||||||
}
|
}
|
||||||
|
@ -2666,6 +2666,8 @@ func TestSqlStore_GetAccountPeers(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
accountID string
|
accountID string
|
||||||
|
nameFilter string
|
||||||
|
ipFilter string
|
||||||
expectedCount int
|
expectedCount int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -2683,11 +2685,29 @@ func TestSqlStore_GetAccountPeers(t *testing.T) {
|
|||||||
accountID: "",
|
accountID: "",
|
||||||
expectedCount: 0,
|
expectedCount: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "should filter peers by name",
|
||||||
|
accountID: "bf1c8084-ba50-4ce7-9439-34653001fc3b",
|
||||||
|
nameFilter: "expiredhost",
|
||||||
|
expectedCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "should filter peers by partial name",
|
||||||
|
accountID: "bf1c8084-ba50-4ce7-9439-34653001fc3b",
|
||||||
|
nameFilter: "host",
|
||||||
|
expectedCount: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "should filter peers by ip",
|
||||||
|
accountID: "bf1c8084-ba50-4ce7-9439-34653001fc3b",
|
||||||
|
ipFilter: "100.64.39.54",
|
||||||
|
expectedCount: 1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
peers, err := store.GetAccountPeers(context.Background(), LockingStrengthShare, tt.accountID)
|
peers, err := store.GetAccountPeers(context.Background(), LockingStrengthShare, tt.accountID, tt.nameFilter, tt.ipFilter)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, peers, tt.expectedCount)
|
require.Len(t, peers, tt.expectedCount)
|
||||||
})
|
})
|
||||||
|
@ -105,7 +105,7 @@ type Store interface {
|
|||||||
RemoveResourceFromGroup(ctx context.Context, accountId string, groupID string, resourceID string) error
|
RemoveResourceFromGroup(ctx context.Context, accountId string, groupID string, resourceID string) error
|
||||||
AddPeerToAccount(ctx context.Context, lockStrength LockingStrength, peer *nbpeer.Peer) error
|
AddPeerToAccount(ctx context.Context, lockStrength LockingStrength, peer *nbpeer.Peer) error
|
||||||
GetPeerByPeerPubKey(ctx context.Context, lockStrength LockingStrength, peerKey string) (*nbpeer.Peer, error)
|
GetPeerByPeerPubKey(ctx context.Context, lockStrength LockingStrength, peerKey string) (*nbpeer.Peer, error)
|
||||||
GetAccountPeers(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*nbpeer.Peer, error)
|
GetAccountPeers(ctx context.Context, lockStrength LockingStrength, accountID, nameFilter, ipFilter string) ([]*nbpeer.Peer, error)
|
||||||
GetUserPeers(ctx context.Context, lockStrength LockingStrength, accountID, userID string) ([]*nbpeer.Peer, error)
|
GetUserPeers(ctx context.Context, lockStrength LockingStrength, accountID, userID string) ([]*nbpeer.Peer, error)
|
||||||
GetPeerByID(ctx context.Context, lockStrength LockingStrength, accountID string, peerID string) (*nbpeer.Peer, error)
|
GetPeerByID(ctx context.Context, lockStrength LockingStrength, accountID string, peerID string) (*nbpeer.Peer, error)
|
||||||
GetPeersByIDs(ctx context.Context, lockStrength LockingStrength, accountID string, peerIDs []string) (map[string]*nbpeer.Peer, error)
|
GetPeersByIDs(ctx context.Context, lockStrength LockingStrength, accountID string, peerIDs []string) (map[string]*nbpeer.Peer, error)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user