add resources to groups

This commit is contained in:
Pascal Fischer
2024-12-11 18:24:32 +01:00
parent 7944b8e843
commit 1af0d2c669
28 changed files with 317 additions and 156 deletions

View File

@ -29,7 +29,6 @@ import (
"github.com/netbirdio/netbird/management/domain"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/geolocation"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/integrated_validator"
"github.com/netbirdio/netbird/management/server/jwtclaims"
@ -98,11 +97,11 @@ type AccountManager interface {
GetPAT(ctx context.Context, accountID string, initiatorUserID string, targetUserID string, tokenID string) (*types.PersonalAccessToken, error)
GetAllPATs(ctx context.Context, accountID string, initiatorUserID string, targetUserID string) ([]*types.PersonalAccessToken, error)
GetUsersFromAccount(ctx context.Context, accountID, userID string) ([]*types.UserInfo, error)
GetGroup(ctx context.Context, accountId, groupID, userID string) (*nbgroup.Group, error)
GetAllGroups(ctx context.Context, accountID, userID string) ([]*nbgroup.Group, error)
GetGroupByName(ctx context.Context, groupName, accountID string) (*nbgroup.Group, error)
SaveGroup(ctx context.Context, accountID, userID string, group *nbgroup.Group) error
SaveGroups(ctx context.Context, accountID, userID string, newGroups []*nbgroup.Group) error
GetGroup(ctx context.Context, accountId, groupID, userID string) (*types.Group, error)
GetAllGroups(ctx context.Context, accountID, userID string) ([]*types.Group, error)
GetGroupByName(ctx context.Context, groupName, accountID string) (*types.Group, error)
SaveGroup(ctx context.Context, accountID, userID string, group *types.Group) error
SaveGroups(ctx context.Context, accountID, userID string, newGroups []*types.Group) error
DeleteGroup(ctx context.Context, accountId, userId, groupID string) error
DeleteGroups(ctx context.Context, accountId, userId string, groupIDs []string) error
GroupAddPeer(ctx context.Context, accountId, groupID, peerID string) error
@ -192,8 +191,8 @@ type DefaultAccountManager struct {
// getJWTGroupsChanges calculates the changes needed to sync a user's JWT groups.
// Returns a bool indicating if there are changes in the JWT group membership, the updated user AutoGroups,
// newly groups to create and an error if any occurred.
func (am *DefaultAccountManager) getJWTGroupsChanges(user *types.User, groups []*nbgroup.Group, groupNames []string) (bool, []string, []*nbgroup.Group, error) {
existedGroupsByName := make(map[string]*nbgroup.Group)
func (am *DefaultAccountManager) getJWTGroupsChanges(user *types.User, groups []*types.Group, groupNames []string) (bool, []string, []*types.Group, error) {
existedGroupsByName := make(map[string]*types.Group)
for _, group := range groups {
existedGroupsByName[group.Name] = group
}
@ -208,21 +207,21 @@ func (am *DefaultAccountManager) getJWTGroupsChanges(user *types.User, groups []
return false, nil, nil, nil
}
newGroupsToCreate := make([]*nbgroup.Group, 0)
newGroupsToCreate := make([]*types.Group, 0)
var modified bool
for _, name := range groupsToAdd {
group, exists := existedGroupsByName[name]
if !exists {
group = &nbgroup.Group{
group = &types.Group{
ID: xid.New().String(),
AccountID: user.AccountID,
Name: name,
Issued: nbgroup.GroupIssuedJWT,
Issued: types.GroupIssuedJWT,
}
newGroupsToCreate = append(newGroupsToCreate, group)
}
if group.Issued == nbgroup.GroupIssuedJWT {
if group.Issued == types.GroupIssuedJWT {
newUserAutoGroups = append(newUserAutoGroups, group.ID)
modified = true
}
@ -1310,7 +1309,7 @@ func (am *DefaultAccountManager) syncJWTGroups(ctx context.Context, accountID st
return fmt.Errorf("error getting account groups: %w", err)
}
groupsMap := make(map[string]*nbgroup.Group, len(groups))
groupsMap := make(map[string]*types.Group, len(groups))
for _, group := range groups {
groupsMap[group.ID] = group
}
@ -1724,15 +1723,15 @@ func (am *DefaultAccountManager) GetNetworksManager() networks.Manager {
// addAllGroup to account object if it doesn't exist
func addAllGroup(account *types.Account) error {
if len(account.Groups) == 0 {
allGroup := &nbgroup.Group{
allGroup := &types.Group{
ID: xid.New().String(),
Name: "All",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
}
for _, peer := range account.Peers {
allGroup.Peers = append(allGroup.Peers, peer.ID)
}
account.Groups = map[string]*nbgroup.Group{allGroup.ID: allGroup}
account.Groups = map[string]*types.Group{allGroup.ID: allGroup}
id := xid.New().String()
@ -1846,18 +1845,18 @@ func userHasAllowedGroup(allowedGroups []string, userGroups []string) bool {
// separateGroups separates user's auto groups into non-JWT and JWT groups.
// Returns the list of standard auto groups and a map of JWT auto groups,
// where the keys are the group names and the values are the group IDs.
func separateGroups(autoGroups []string, allGroups []*nbgroup.Group) ([]string, map[string]string) {
func separateGroups(autoGroups []string, allGroups []*types.Group) ([]string, map[string]string) {
newAutoGroups := make([]string, 0)
jwtAutoGroups := make(map[string]string) // map of group name to group ID
allGroupsMap := make(map[string]*nbgroup.Group, len(allGroups))
allGroupsMap := make(map[string]*types.Group, len(allGroups))
for _, group := range allGroups {
allGroupsMap[group.ID] = group
}
for _, id := range autoGroups {
if group, ok := allGroupsMap[id]; ok {
if group.Issued == nbgroup.GroupIssuedJWT {
if group.Issued == types.GroupIssuedJWT {
jwtAutoGroups[group.Name] = id
} else {
newAutoGroups = append(newAutoGroups, id)

View File

@ -16,7 +16,6 @@ import (
"github.com/netbirdio/netbird/route"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/status"
)
@ -48,7 +47,7 @@ func (am *DefaultAccountManager) CheckGroupPermissions(ctx context.Context, acco
}
// GetGroup returns a specific group by groupID in an account
func (am *DefaultAccountManager) GetGroup(ctx context.Context, accountID, groupID, userID string) (*nbgroup.Group, error) {
func (am *DefaultAccountManager) GetGroup(ctx context.Context, accountID, groupID, userID string) (*types.Group, error) {
if err := am.CheckGroupPermissions(ctx, accountID, userID); err != nil {
return nil, err
}
@ -56,7 +55,7 @@ func (am *DefaultAccountManager) GetGroup(ctx context.Context, accountID, groupI
}
// GetAllGroups returns all groups in an account
func (am *DefaultAccountManager) GetAllGroups(ctx context.Context, accountID, userID string) ([]*nbgroup.Group, error) {
func (am *DefaultAccountManager) GetAllGroups(ctx context.Context, accountID, userID string) ([]*types.Group, error) {
if err := am.CheckGroupPermissions(ctx, accountID, userID); err != nil {
return nil, err
}
@ -64,21 +63,21 @@ func (am *DefaultAccountManager) GetAllGroups(ctx context.Context, accountID, us
}
// GetGroupByName filters all groups in an account by name and returns the one with the most peers
func (am *DefaultAccountManager) GetGroupByName(ctx context.Context, groupName, accountID string) (*nbgroup.Group, error) {
func (am *DefaultAccountManager) GetGroupByName(ctx context.Context, groupName, accountID string) (*types.Group, error) {
return am.Store.GetGroupByName(ctx, store.LockingStrengthShare, accountID, groupName)
}
// SaveGroup object of the peers
func (am *DefaultAccountManager) SaveGroup(ctx context.Context, accountID, userID string, newGroup *nbgroup.Group) error {
func (am *DefaultAccountManager) SaveGroup(ctx context.Context, accountID, userID string, newGroup *types.Group) error {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
return am.SaveGroups(ctx, accountID, userID, []*nbgroup.Group{newGroup})
return am.SaveGroups(ctx, accountID, userID, []*types.Group{newGroup})
}
// SaveGroups adds new groups to the account.
// Note: This function does not acquire the global lock.
// It is the caller's responsibility to ensure proper locking is in place before invoking this method.
func (am *DefaultAccountManager) SaveGroups(ctx context.Context, accountID, userID string, groups []*nbgroup.Group) error {
func (am *DefaultAccountManager) SaveGroups(ctx context.Context, accountID, userID string, groups []*types.Group) error {
user, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthShare, userID)
if err != nil {
return err
@ -93,7 +92,7 @@ func (am *DefaultAccountManager) SaveGroups(ctx context.Context, accountID, user
}
var eventsToStore []func()
var groupsToSave []*nbgroup.Group
var groupsToSave []*types.Group
var updateAccountPeers bool
err = am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
@ -138,7 +137,7 @@ func (am *DefaultAccountManager) SaveGroups(ctx context.Context, accountID, user
}
// prepareGroupEvents prepares a list of event functions to be stored.
func (am *DefaultAccountManager) prepareGroupEvents(ctx context.Context, transaction store.Store, accountID, userID string, newGroup *nbgroup.Group) []func() {
func (am *DefaultAccountManager) prepareGroupEvents(ctx context.Context, transaction store.Store, accountID, userID string, newGroup *types.Group) []func() {
var eventsToStore []func()
addedPeers := make([]string, 0)
@ -226,7 +225,7 @@ func (am *DefaultAccountManager) DeleteGroups(ctx context.Context, accountID, us
var allErrors error
var groupIDsToDelete []string
var deletedGroups []*nbgroup.Group
var deletedGroups []*types.Group
err = am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
for _, groupID := range groupIDs {
@ -267,7 +266,7 @@ func (am *DefaultAccountManager) GroupAddPeer(ctx context.Context, accountID, gr
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
var group *nbgroup.Group
var group *types.Group
var updateAccountPeers bool
var err error
@ -303,12 +302,53 @@ func (am *DefaultAccountManager) GroupAddPeer(ctx context.Context, accountID, gr
return nil
}
// GroupAddResource appends resource to the group
func (am *DefaultAccountManager) GroupAddResource(ctx context.Context, accountID, groupID string, resource types.Resource) error {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
var group *types.Group
var updateAccountPeers bool
var err error
err = am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
group, err = transaction.GetGroupByID(context.Background(), store.LockingStrengthUpdate, accountID, groupID)
if err != nil {
return err
}
if updated := group.AddResource(resource); !updated {
return nil
}
updateAccountPeers, err = areGroupChangesAffectPeers(ctx, transaction, accountID, []string{groupID})
if err != nil {
return err
}
if err = transaction.IncrementNetworkSerial(ctx, store.LockingStrengthUpdate, accountID); err != nil {
return err
}
return transaction.SaveGroup(ctx, store.LockingStrengthUpdate, group)
})
if err != nil {
return err
}
if updateAccountPeers {
am.updateAccountPeers(ctx, accountID)
}
return nil
}
// GroupDeletePeer removes peer from the group
func (am *DefaultAccountManager) GroupDeletePeer(ctx context.Context, accountID, groupID, peerID string) error {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
var group *nbgroup.Group
var group *types.Group
var updateAccountPeers bool
var err error
@ -344,13 +384,54 @@ func (am *DefaultAccountManager) GroupDeletePeer(ctx context.Context, accountID,
return nil
}
// GroupDeleteResource removes resource from the group
func (am *DefaultAccountManager) GroupDeleteResource(ctx context.Context, accountID, groupID string, resource types.Resource) error {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
var group *types.Group
var updateAccountPeers bool
var err error
err = am.Store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
group, err = transaction.GetGroupByID(context.Background(), store.LockingStrengthUpdate, accountID, groupID)
if err != nil {
return err
}
if updated := group.RemoveResource(resource); !updated {
return nil
}
updateAccountPeers, err = areGroupChangesAffectPeers(ctx, transaction, accountID, []string{groupID})
if err != nil {
return err
}
if err = transaction.IncrementNetworkSerial(ctx, store.LockingStrengthUpdate, accountID); err != nil {
return err
}
return transaction.SaveGroup(ctx, store.LockingStrengthUpdate, group)
})
if err != nil {
return err
}
if updateAccountPeers {
am.updateAccountPeers(ctx, accountID)
}
return nil
}
// validateNewGroup validates the new group for existence and required fields.
func validateNewGroup(ctx context.Context, transaction store.Store, accountID string, newGroup *nbgroup.Group) error {
if newGroup.ID == "" && newGroup.Issued != nbgroup.GroupIssuedAPI {
func validateNewGroup(ctx context.Context, transaction store.Store, accountID string, newGroup *types.Group) error {
if newGroup.ID == "" && newGroup.Issued != types.GroupIssuedAPI {
return status.Errorf(status.InvalidArgument, "%s group without ID set", newGroup.Issued)
}
if newGroup.ID == "" && newGroup.Issued == nbgroup.GroupIssuedAPI {
if newGroup.ID == "" && newGroup.Issued == types.GroupIssuedAPI {
existingGroup, err := transaction.GetGroupByName(ctx, store.LockingStrengthShare, accountID, newGroup.Name)
if err != nil {
if s, ok := status.FromError(err); !ok || s.Type() != status.NotFound {
@ -377,9 +458,9 @@ func validateNewGroup(ctx context.Context, transaction store.Store, accountID st
return nil
}
func validateDeleteGroup(ctx context.Context, transaction store.Store, group *nbgroup.Group, userID string) error {
func validateDeleteGroup(ctx context.Context, transaction store.Store, group *types.Group, userID string) error {
// disable a deleting integration group if the initiator is not an admin service user
if group.Issued == nbgroup.GroupIssuedIntegration {
if group.Issued == types.GroupIssuedIntegration {
executingUser, err := transaction.GetUserByUserID(ctx, store.LockingStrengthShare, userID)
if err != nil {
return err
@ -417,7 +498,7 @@ func validateDeleteGroup(ctx context.Context, transaction store.Store, group *nb
}
// checkGroupLinkedToSettings verifies if a group is linked to any settings in the account.
func checkGroupLinkedToSettings(ctx context.Context, transaction store.Store, group *nbgroup.Group) error {
func checkGroupLinkedToSettings(ctx context.Context, transaction store.Store, group *types.Group) error {
dnsSettings, err := transaction.GetAccountDNSSettings(ctx, store.LockingStrengthShare, group.AccountID)
if err != nil {
return err

View File

@ -11,8 +11,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
nbdns "github.com/netbirdio/netbird/dns"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/netbird/route"
@ -33,22 +34,22 @@ func TestDefaultAccountManager_CreateGroup(t *testing.T) {
t.Error("failed to init testing account")
}
for _, group := range account.Groups {
group.Issued = nbgroup.GroupIssuedIntegration
group.Issued = types.GroupIssuedIntegration
err = am.SaveGroup(context.Background(), account.Id, groupAdminUserID, group)
if err != nil {
t.Errorf("should allow to create %s groups", nbgroup.GroupIssuedIntegration)
t.Errorf("should allow to create %s groups", types.GroupIssuedIntegration)
}
}
for _, group := range account.Groups {
group.Issued = nbgroup.GroupIssuedJWT
group.Issued = types.GroupIssuedJWT
err = am.SaveGroup(context.Background(), account.Id, groupAdminUserID, group)
if err != nil {
t.Errorf("should allow to create %s groups", nbgroup.GroupIssuedJWT)
t.Errorf("should allow to create %s groups", types.GroupIssuedJWT)
}
}
for _, group := range account.Groups {
group.Issued = nbgroup.GroupIssuedAPI
group.Issued = types.GroupIssuedAPI
group.ID = ""
err = am.SaveGroup(context.Background(), account.Id, groupAdminUserID, group)
if err == nil {
@ -146,13 +147,13 @@ func TestDefaultAccountManager_DeleteGroups(t *testing.T) {
manager, account, err := initTestGroupAccount(am)
assert.NoError(t, err, "Failed to init testing account")
groups := make([]*nbgroup.Group, 10)
groups := make([]*types.Group, 10)
for i := 0; i < 10; i++ {
groups[i] = &nbgroup.Group{
groups[i] = &types.Group{
ID: fmt.Sprintf("group-%d", i+1),
AccountID: account.Id,
Name: fmt.Sprintf("group-%d", i+1),
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
}
}
@ -272,59 +273,59 @@ func initTestGroupAccount(am *DefaultAccountManager) (*DefaultAccountManager, *t
accountID := "testingAcc"
domain := "example.com"
groupForRoute := &nbgroup.Group{
groupForRoute := &types.Group{
ID: "grp-for-route",
AccountID: "account-id",
Name: "Group for route",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForRoute2 := &nbgroup.Group{
groupForRoute2 := &types.Group{
ID: "grp-for-route2",
AccountID: "account-id",
Name: "Group for route",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForNameServerGroups := &nbgroup.Group{
groupForNameServerGroups := &types.Group{
ID: "grp-for-name-server-grp",
AccountID: "account-id",
Name: "Group for name server groups",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForPolicies := &nbgroup.Group{
groupForPolicies := &types.Group{
ID: "grp-for-policies",
AccountID: "account-id",
Name: "Group for policies",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForSetupKeys := &nbgroup.Group{
groupForSetupKeys := &types.Group{
ID: "grp-for-keys",
AccountID: "account-id",
Name: "Group for setup keys",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForUsers := &nbgroup.Group{
groupForUsers := &types.Group{
ID: "grp-for-users",
AccountID: "account-id",
Name: "Group for users",
Issued: nbgroup.GroupIssuedAPI,
Issued: types.GroupIssuedAPI,
Peers: make([]string, 0),
}
groupForIntegration := &nbgroup.Group{
groupForIntegration := &types.Group{
ID: "grp-for-integration",
AccountID: "account-id",
Name: "Group for users integration",
Issued: nbgroup.GroupIssuedIntegration,
Issued: types.GroupIssuedIntegration,
Peers: make([]string, 0),
}
@ -393,7 +394,7 @@ func initTestGroupAccount(am *DefaultAccountManager) (*DefaultAccountManager, *t
func TestGroupAccountPeersUpdate(t *testing.T) {
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
err := manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err := manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "groupA",
Name: "GroupA",
@ -430,7 +431,7 @@ func TestGroupAccountPeersUpdate(t *testing.T) {
close(done)
}()
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err := manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupB",
Name: "GroupB",
Peers: []string{peer1.ID, peer2.ID},
@ -523,7 +524,7 @@ func TestGroupAccountPeersUpdate(t *testing.T) {
close(done)
}()
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err := manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID},
@ -592,7 +593,7 @@ func TestGroupAccountPeersUpdate(t *testing.T) {
close(done)
}()
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err := manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupC",
Name: "GroupC",
Peers: []string{peer1.ID, peer3.ID},
@ -633,7 +634,7 @@ func TestGroupAccountPeersUpdate(t *testing.T) {
close(done)
}()
err = manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err = manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID, peer3.ID},

View File

@ -668,6 +668,10 @@ components:
description: Count of peers associated to the group
type: integer
example: 2
resources_count:
description: Count of resources associated to the group
type: integer
example: 5
issued:
description: How the group was issued (api, integration, jwt)
type: string
@ -677,6 +681,7 @@ components:
- id
- name
- peers_count
- resources_count
GroupRequest:
type: object
properties:
@ -690,6 +695,10 @@ components:
items:
type: string
example: "ch8i4ug6lnn4g9hqv7m1"
resources:
type: array
items:
$ref: '#/components/schemas/Resource'
required:
- name
Group:
@ -702,8 +711,13 @@ components:
type: array
items:
$ref: '#/components/schemas/PeerMinimum'
resources:
type: array
items:
$ref: '#/components/schemas/Resource'
required:
- peers
- resources
PolicyRuleMinimum:
type: object
properties:

View File

@ -379,7 +379,11 @@ type Group struct {
Peers []PeerMinimum `json:"peers"`
// PeersCount Count of peers associated to the group
PeersCount int `json:"peers_count"`
PeersCount int `json:"peers_count"`
Resources []Resource `json:"resources"`
// ResourcesCount Count of resources associated to the group
ResourcesCount int `json:"resources_count"`
}
// GroupIssued How the group was issued (api, integration, jwt)
@ -398,6 +402,9 @@ type GroupMinimum struct {
// PeersCount Count of peers associated to the group
PeersCount int `json:"peers_count"`
// ResourcesCount Count of resources associated to the group
ResourcesCount int `json:"resources_count"`
}
// GroupMinimumIssued How the group was issued (api, integration, jwt)
@ -409,7 +416,8 @@ type GroupRequest struct {
Name string `json:"name"`
// Peers List of peers ids
Peers *[]string `json:"peers,omitempty"`
Peers *[]string `json:"peers,omitempty"`
Resources *[]Resource `json:"resources,omitempty"`
}
// Location Describe geographical location information
@ -1062,7 +1070,7 @@ type ProcessCheck struct {
// Resource defines model for Resource.
type Resource struct {
// Id Resource ID
// Id ID of the resource
Id string `json:"id"`
Type ResourceType `json:"type"`
}

View File

@ -9,9 +9,9 @@ import (
"github.com/netbirdio/netbird/management/server/http/configs"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/netbird/management/server"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/http/util"
"github.com/netbirdio/netbird/management/server/jwtclaims"
@ -129,10 +129,21 @@ func (h *handler) updateGroup(w http.ResponseWriter, r *http.Request) {
} else {
peers = *req.Peers
}
group := nbgroup.Group{
resources := make([]types.Resource, 0)
if req.Resources != nil {
for _, res := range *req.Resources {
resource := types.Resource{}
resource.FromAPIRequest(&res)
resources = append(resources, resource)
}
}
group := types.Group{
ID: groupID,
Name: req.Name,
Peers: peers,
Resources: resources,
Issued: existingGroup.Issued,
IntegrationReference: existingGroup.IntegrationReference,
}
@ -179,10 +190,21 @@ func (h *handler) createGroup(w http.ResponseWriter, r *http.Request) {
} else {
peers = *req.Peers
}
group := nbgroup.Group{
Name: req.Name,
Peers: peers,
Issued: nbgroup.GroupIssuedAPI,
resources := make([]types.Resource, 0)
if req.Resources != nil {
for _, res := range *req.Resources {
resource := types.Resource{}
resource.FromAPIRequest(&res)
resources = append(resources, resource)
}
}
group := types.Group{
Name: req.Name,
Peers: peers,
Resources: resources,
Issued: types.GroupIssuedAPI,
}
err = h.accountManager.SaveGroup(r.Context(), accountID, userID, &group)
@ -259,12 +281,17 @@ func (h *handler) getGroup(w http.ResponseWriter, r *http.Request) {
}
func toGroupResponse(peers []*nbpeer.Peer, group *nbgroup.Group) *api.Group {
func toGroupResponse(peers []*nbpeer.Peer, group *types.Group) *api.Group {
peersMap := make(map[string]*nbpeer.Peer, len(peers))
for _, peer := range peers {
peersMap[peer.ID] = peer
}
resMap := make(map[string]types.Resource, len(peers))
for _, peer := range peers {
peersMap[peer.ID] = peer
}
cache := make(map[string]api.PeerMinimum)
gr := api.Group{
Id: group.ID,
@ -290,5 +317,21 @@ func toGroupResponse(peers []*nbpeer.Peer, group *nbgroup.Group) *api.Group {
gr.PeersCount = len(gr.Peers)
for _, res := range group.Resources {
_, ok := cache[res.ID]
if !ok {
peer, ok := peersMap[pid]
if !ok {
continue
}
peerResp := api.PeerMinimum{
Id: peer.ID,
Name: peer.Name,
}
cache[pid] = peerResp
gr.Peers = append(gr.Peers, peerResp)
}
}
return &gr
}

View File

@ -16,8 +16,9 @@ import (
"github.com/magiconair/properties/assert"
"golang.org/x/exp/maps"
"github.com/netbirdio/netbird/management/server"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/http/util"
"github.com/netbirdio/netbird/management/server/jwtclaims"
@ -31,20 +32,20 @@ var TestPeers = map[string]*nbpeer.Peer{
"B": {Key: "B", ID: "peer-B-ID", IP: net.ParseIP("200.200.200.200")},
}
func initGroupTestData(initGroups ...*nbgroup.Group) *handler {
func initGroupTestData(initGroups ...*types.Group) *handler {
return &handler{
accountManager: &mock_server.MockAccountManager{
SaveGroupFunc: func(_ context.Context, accountID, userID string, group *nbgroup.Group) error {
SaveGroupFunc: func(_ context.Context, accountID, userID string, group *types.Group) error {
if !strings.HasPrefix(group.ID, "id-") {
group.ID = "id-was-set"
}
return nil
},
GetGroupFunc: func(_ context.Context, _, groupID, _ string) (*nbgroup.Group, error) {
groups := map[string]*nbgroup.Group{
"id-jwt-group": {ID: "id-jwt-group", Name: "From JWT", Issued: nbgroup.GroupIssuedJWT},
"id-existed": {ID: "id-existed", Peers: []string{"A", "B"}, Issued: nbgroup.GroupIssuedAPI},
"id-all": {ID: "id-all", Name: "All", Issued: nbgroup.GroupIssuedAPI},
GetGroupFunc: func(_ context.Context, _, groupID, _ string) (*types.Group, error) {
groups := map[string]*types.Group{
"id-jwt-group": {ID: "id-jwt-group", Name: "From JWT", Issued: types.GroupIssuedJWT},
"id-existed": {ID: "id-existed", Peers: []string{"A", "B"}, Issued: types.GroupIssuedAPI},
"id-all": {ID: "id-all", Name: "All", Issued: types.GroupIssuedAPI},
}
for _, group := range initGroups {
@ -61,9 +62,9 @@ func initGroupTestData(initGroups ...*nbgroup.Group) *handler {
GetAccountIDFromTokenFunc: func(_ context.Context, claims jwtclaims.AuthorizationClaims) (string, string, error) {
return claims.AccountId, claims.UserId, nil
},
GetGroupByNameFunc: func(ctx context.Context, groupName, _ string) (*nbgroup.Group, error) {
GetGroupByNameFunc: func(ctx context.Context, groupName, _ string) (*types.Group, error) {
if groupName == "All" {
return &nbgroup.Group{ID: "id-all", Name: "All", Issued: nbgroup.GroupIssuedAPI}, nil
return &types.Group{ID: "id-all", Name: "All", Issued: types.GroupIssuedAPI}, nil
}
return nil, fmt.Errorf("unknown group name")
@ -120,7 +121,7 @@ func TestGetGroup(t *testing.T) {
},
}
group := &nbgroup.Group{
group := &types.Group{
ID: "idofthegroup",
Name: "Group",
}

View File

@ -10,7 +10,6 @@ import (
log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/management/server"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/http/configs"
"github.com/netbirdio/netbird/management/server/http/util"
@ -200,7 +199,7 @@ func (h *Handler) GetAllPeers(w http.ResponseWriter, r *http.Request) {
return
}
groupsMap := map[string]*nbgroup.Group{}
groupsMap := map[string]*types.Group{}
groups, _ := h.accountManager.GetAllGroups(r.Context(), accountID, userID)
for _, group := range groups {
groupsMap[group.ID] = group
@ -325,7 +324,7 @@ func peerToAccessiblePeer(peer *nbpeer.Peer, dnsDomain string) api.AccessiblePee
}
}
func toGroupsInfo(groups map[string]*nbgroup.Group, peerID string) []api.GroupMinimum {
func toGroupsInfo(groups map[string]*types.Group, peerID string) []api.GroupMinimum {
groupsInfo := []api.GroupMinimum{}
groupsChecked := make(map[string]struct{})
for _, group := range groups {

View File

@ -15,7 +15,6 @@ import (
"github.com/gorilla/mux"
"golang.org/x/exp/maps"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
@ -111,7 +110,7 @@ func initTestMetaData(peers ...*nbpeer.Peer) *Handler {
regularUser: types.NewRegularUser(regularUser),
serviceUser: srvUser,
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"group1": {
ID: "group1",
AccountID: accountID,

View File

@ -9,7 +9,6 @@ import (
"github.com/netbirdio/netbird/management/server"
"github.com/netbirdio/netbird/management/server/geolocation"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/http/configs"
"github.com/netbirdio/netbird/management/server/http/util"
@ -361,8 +360,8 @@ func (h *handler) getPolicy(w http.ResponseWriter, r *http.Request) {
util.WriteJSONObject(r.Context(), w, resp)
}
func toPolicyResponse(groups []*nbgroup.Group, policy *types.Policy) *api.Policy {
groupsMap := make(map[string]*nbgroup.Group)
func toPolicyResponse(groups []*types.Group, policy *types.Policy) *api.Policy {
groupsMap := make(map[string]*types.Group)
for _, group := range groups {
groupsMap[group.ID] = group
}

View File

@ -10,7 +10,6 @@ import (
"strings"
"testing"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/types"
@ -45,8 +44,8 @@ func initPoliciesTestData(policies ...*types.Policy) *handler {
}
return policy, nil
},
GetAllGroupsFunc: func(ctx context.Context, accountID, userID string) ([]*nbgroup.Group, error) {
return []*nbgroup.Group{{ID: "F"}, {ID: "G"}}, nil
GetAllGroupsFunc: func(ctx context.Context, accountID, userID string) ([]*types.Group, error) {
return []*types.Group{{ID: "F"}, {ID: "G"}}, nil
},
GetAccountIDFromTokenFunc: func(_ context.Context, claims jwtclaims.AuthorizationClaims) (string, string, error) {
return claims.AccountId, claims.UserId, nil
@ -59,7 +58,7 @@ func initPoliciesTestData(policies ...*types.Policy) *handler {
Policies: []*types.Policy{
{ID: "id-existed"},
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"F": {ID: "F"},
"G": {ID: "G"},
},

View File

@ -4,7 +4,6 @@ import (
"context"
"github.com/netbirdio/netbird/management/server/account"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
)
@ -14,7 +13,7 @@ type IntegratedValidator interface {
ValidatePeer(ctx context.Context, update *nbpeer.Peer, peer *nbpeer.Peer, userID string, accountID string, dnsDomain string, peersGroup []string, extraSettings *account.ExtraSettings) (*nbpeer.Peer, bool, error)
PreparePeer(ctx context.Context, accountID string, peer *nbpeer.Peer, peersGroup []string, extraSettings *account.ExtraSettings) *nbpeer.Peer
IsNotValidPeer(ctx context.Context, accountID string, peer *nbpeer.Peer, peersGroup []string, extraSettings *account.ExtraSettings) (bool, bool, error)
GetValidatedPeers(accountID string, groups map[string]*nbgroup.Group, peers map[string]*nbpeer.Peer, extraSettings *account.ExtraSettings) (map[string]struct{}, error)
GetValidatedPeers(accountID string, groups map[string]*types.Group, peers map[string]*nbpeer.Peer, extraSettings *account.ExtraSettings) (map[string]struct{}, error)
PeerDeleted(ctx context.Context, accountID, peerID string) error
SetPeerInvalidationListener(fn func(accountID string))
Stop(ctx context.Context)

View File

@ -11,7 +11,6 @@ import (
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/store"
)
@ -306,7 +305,7 @@ func validateNSList(list []nbdns.NameServer) error {
return nil
}
func validateGroups(list []string, groups map[string]*nbgroup.Group) error {
func validateGroups(list []string, groups map[string]*types.Group) error {
if len(list) == 0 {
return status.Errorf(status.InvalidArgument, "the list of group IDs should not be empty")
}

View File

@ -11,7 +11,6 @@ import (
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/store"
"github.com/netbirdio/netbird/management/server/telemetry"
@ -844,12 +843,12 @@ func initTestNSAccount(t *testing.T, am *DefaultAccountManager) (*types.Account,
account.NameServerGroups[existingNSGroup.ID] = &existingNSGroup
newGroup1 := &nbgroup.Group{
newGroup1 := &types.Group{
ID: group1ID,
Name: group1ID,
}
newGroup2 := &nbgroup.Group{
newGroup2 := &types.Group{
ID: group2ID,
Name: group2ID,
}
@ -946,7 +945,7 @@ func TestNameServerAccountPeersUpdate(t *testing.T) {
var newNameServerGroupA *nbdns.NameServerGroup
var newNameServerGroupB *nbdns.NameServerGroup
err := manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err := manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "groupA",
Name: "GroupA",

View File

@ -24,7 +24,6 @@ import (
"github.com/netbirdio/netbird/management/proto"
nbAccount "github.com/netbirdio/netbird/management/server/account"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/netbirdio/netbird/management/server/store"
@ -283,8 +282,8 @@ func TestAccountManager_GetNetworkMapWithPolicy(t *testing.T) {
return
}
var (
group1 nbgroup.Group
group2 nbgroup.Group
group1 types.Group
group2 types.Group
)
group1.ID = xid.New().String()
@ -751,7 +750,7 @@ func setupTestAccountManager(b *testing.B, peers int, groups int) (*DefaultAccou
account.Policies = make([]*types.Policy, 0, groups)
for i := 0; i < groups; i++ {
groupID := fmt.Sprintf("group-%d", i)
group := &nbgroup.Group{
group := &types.Group{
ID: groupID,
Name: fmt.Sprintf("Group %d", i),
}
@ -1286,7 +1285,7 @@ func TestPeerAccountPeersUpdate(t *testing.T) {
err := manager.DeletePolicy(context.Background(), account.Id, account.Policies[0].ID, userID)
require.NoError(t, err)
err = manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err = manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "groupA",
Name: "GroupA",

View File

@ -11,7 +11,6 @@ import (
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/netbirdio/netbird/management/server/status"
)
@ -239,7 +238,7 @@ func getValidPostureCheckIDs(postureChecks map[string]*posture.Checks, postureCh
}
// getValidGroupIDs filters and returns only the valid group IDs from the provided list.
func getValidGroupIDs(groups map[string]*nbgroup.Group, groupIDs []string) []string {
func getValidGroupIDs(groups map[string]*types.Group, groupIDs []string) []string {
validIDs := make([]string, 0, len(groupIDs))
for _, id := range groupIDs {
if _, exists := groups[id]; exists {

View File

@ -10,7 +10,6 @@ import (
"github.com/stretchr/testify/assert"
"golang.org/x/exp/slices"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/netbirdio/netbird/management/server/types"
@ -60,7 +59,7 @@ func TestAccount_getPeersByPolicy(t *testing.T) {
Status: &nbpeer.PeerStatus{},
},
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"GroupAll": {
ID: "GroupAll",
Name: "All",
@ -308,7 +307,7 @@ func TestAccount_getPeersByPolicyDirect(t *testing.T) {
Status: &nbpeer.PeerStatus{},
},
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"GroupAll": {
ID: "GroupAll",
Name: "All",
@ -583,7 +582,7 @@ func TestAccount_getPeersByPolicyPostureChecks(t *testing.T) {
},
},
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"GroupAll": {
ID: "GroupAll",
Name: "All",
@ -830,7 +829,7 @@ func sortFunc() func(a *types.FirewallRule, b *types.FirewallRule) int {
func TestPolicyAccountPeersUpdate(t *testing.T) {
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
err := manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err := manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "groupA",
Name: "GroupA",

View File

@ -13,9 +13,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/domain"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/store"
"github.com/netbirdio/netbird/management/server/telemetry"
@ -1096,7 +1097,7 @@ func TestGetNetworkMap_RouteSyncPeerGroups(t *testing.T) {
groups, err := am.Store.GetAccountGroups(context.Background(), store.LockingStrengthShare, account.Id)
require.NoError(t, err)
var groupHA1, groupHA2 *nbgroup.Group
var groupHA1, groupHA2 *types.Group
for _, group := range groups {
switch group.Name {
case routeGroupHA1:
@ -1204,7 +1205,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
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")
newGroup := &nbgroup.Group{
newGroup := &types.Group{
ID: xid.New().String(),
Name: "peer1 group",
Peers: []string{peer1ID},
@ -1441,7 +1442,7 @@ func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*types.Accou
return nil, err
}
newGroup := []*nbgroup.Group{
newGroup := []*types.Group{
{
ID: routeGroup1,
Name: routeGroup1,
@ -1557,7 +1558,7 @@ func TestAccount_getPeersRoutesFirewall(t *testing.T) {
Status: &nbpeer.PeerStatus{},
},
},
Groups: map[string]*nbgroup.Group{
Groups: map[string]*types.Group{
"routingPeer1": {
ID: "routingPeer1",
Name: "RoutingPeer1",
@ -1911,7 +1912,7 @@ func TestRouteAccountPeersUpdate(t *testing.T) {
account, err := initTestRouteAccount(t, manager)
require.NoError(t, err, "failed to init testing account")
err = manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err = manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "groupA",
Name: "GroupA",
@ -2107,7 +2108,7 @@ func TestRouteAccountPeersUpdate(t *testing.T) {
close(done)
}()
err = manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err = manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupB",
Name: "GroupB",
Peers: []string{peer1ID},

View File

@ -15,7 +15,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/netbirdio/netbird/management/server/activity"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/types"
)
@ -31,7 +30,7 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
t.Fatal(err)
}
err = manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
err = manager.SaveGroups(context.Background(), account.Id, userID, []*types.Group{
{
ID: "group_1",
Name: "group_name_1",
@ -106,7 +105,7 @@ func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
t.Fatal(err)
}
err = manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err = manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "group_1",
Name: "group_name_1",
Peers: []string{},
@ -115,7 +114,7 @@ func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
t.Fatal(err)
}
err = manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err = manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "group_2",
Name: "group_name_2",
Peers: []string{},
@ -400,7 +399,7 @@ func TestSetupKey_Copy(t *testing.T) {
func TestSetupKeyAccountPeersUpdate(t *testing.T) {
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err := manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID, peer3.ID},

View File

@ -11,7 +11,6 @@ import (
"github.com/rs/xid"
log "github.com/sirupsen/logrus"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/management/server/types"
@ -148,7 +147,7 @@ func restore(ctx context.Context, file string) (*FileStore, error) {
// Set API as issuer for groups which has not this field
for _, group := range account.Groups {
if group.Issued == "" {
group.Issued = nbgroup.GroupIssuedAPI
group.Issued = types.GroupIssuedAPI
}
}

View File

@ -24,7 +24,6 @@ import (
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/account"
nbgroup "github.com/netbirdio/netbird/management/server/group"
resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types"
routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types"
networkTypes "github.com/netbirdio/netbird/management/server/networks/types"
@ -90,7 +89,7 @@ func NewSqlStore(ctx context.Context, db *gorm.DB, storeEngine Engine, metrics t
return nil, fmt.Errorf("migrate: %w", err)
}
err = db.AutoMigrate(
&types.SetupKey{}, &nbpeer.Peer{}, &types.User{}, &types.PersonalAccessToken{}, &nbgroup.Group{},
&types.SetupKey{}, &nbpeer.Peer{}, &types.User{}, &types.PersonalAccessToken{}, &types.Group{},
&types.Account{}, &types.Policy{}, &types.PolicyRule{}, &route.Route{}, &nbdns.NameServerGroup{},
&installation{}, &account.ExtraSettings{}, &posture.Checks{}, &nbpeer.NetworkAddress{},
&networkTypes.Network{}, &routerTypes.NetworkRouter{}, &resourceTypes.NetworkResource{},

View File

@ -19,8 +19,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
nbdns "github.com/netbirdio/netbird/dns"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbdns "github.com/netbirdio/netbird/dns"
resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types"
routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types"
networkTypes "github.com/netbirdio/netbird/management/server/networks/types"
@ -119,7 +120,7 @@ func runLargeTest(t *testing.T, store Store) {
}
account.Routes[route.ID] = route
group = &nbgroup.Group{
group = &types.Group{
ID: fmt.Sprintf("group-id-%d", n),
AccountID: account.Id,
Name: fmt.Sprintf("group-id-%d", n),

View File

@ -20,8 +20,6 @@ import (
"github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/types"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/util"
@ -75,9 +73,9 @@ type Store interface {
DeleteHashedPAT2TokenIDIndex(hashedToken string) error
DeleteTokenID2UserIDIndex(tokenID string) error
GetAccountGroups(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*nbgroup.Group, error)
GetGroupByID(ctx context.Context, lockStrength LockingStrength, groupID, accountID string) (*nbgroup.Group, error)
GetGroupByName(ctx context.Context, lockStrength LockingStrength, groupName, accountID string) (*nbgroup.Group, error)
GetAccountGroups(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*types.Group, error)
GetGroupByID(ctx context.Context, lockStrength LockingStrength, groupID, accountID string) (*types.Group, error)
GetGroupByName(ctx context.Context, lockStrength LockingStrength, groupName, accountID string) (*types.Group, error)
GetGroupsByIDs(ctx context.Context, lockStrength LockingStrength, accountID string, groupIDs []string) (map[string]*nbgroup.Group, error)
SaveGroups(ctx context.Context, lockStrength LockingStrength, groups []*nbgroup.Group) error
SaveGroup(ctx context.Context, lockStrength LockingStrength, group *nbgroup.Group) error

View File

@ -16,7 +16,6 @@ import (
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/domain"
nbgroup "github.com/netbirdio/netbird/management/server/group"
resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types"
routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types"
@ -59,8 +58,8 @@ type Account struct {
PeersG []nbpeer.Peer `json:"-" gorm:"foreignKey:AccountID;references:id"`
Users map[string]*User `gorm:"-"`
UsersG []User `json:"-" gorm:"foreignKey:AccountID;references:id"`
Groups map[string]*nbgroup.Group `gorm:"-"`
GroupsG []nbgroup.Group `json:"-" gorm:"foreignKey:AccountID;references:id"`
Groups map[string]*types.Group `gorm:"-"`
GroupsG []types.Group `json:"-" gorm:"foreignKey:AccountID;references:id"`
Policies []*Policy `gorm:"foreignKey:AccountID;references:id"`
Routes map[route.ID]*route.Route `gorm:"-"`
RoutesG []route.Route `json:"-" gorm:"foreignKey:AccountID;references:id"`
@ -214,7 +213,7 @@ func (a *Account) GetRoutesByPrefixOrDomains(prefix netip.Prefix, domains domain
}
// GetGroup returns a group by ID if exists, nil otherwise
func (a *Account) GetGroup(groupID string) *nbgroup.Group {
func (a *Account) GetGroup(groupID string) *types.Group {
return a.Groups[groupID]
}
@ -609,7 +608,7 @@ func (a *Account) FindUser(userID string) (*User, error) {
}
// FindGroupByName looks for a given group in the Account by name or returns error if the group wasn't found.
func (a *Account) FindGroupByName(groupName string) (*nbgroup.Group, error) {
func (a *Account) FindGroupByName(groupName string) (*types.Group, error) {
for _, group := range a.Groups {
if group.Name == groupName {
return group, nil

View File

@ -1,6 +1,8 @@
package group
package types
import "github.com/netbirdio/netbird/management/server/integration_reference"
import (
"github.com/netbirdio/netbird/management/server/integration_reference"
)
const (
GroupIssuedAPI = "api"
@ -25,6 +27,9 @@ type Group struct {
// Peers list of the group
Peers []string `gorm:"serializer:json"`
// Resources contains a list of resources in that group
Resources []Resource `gorm:"serializer:json"`
IntegrationReference integration_reference.IntegrationReference `gorm:"embedded;embeddedPrefix:integration_ref_"`
}
@ -39,9 +44,11 @@ func (g *Group) Copy() *Group {
Name: g.Name,
Issued: g.Issued,
Peers: make([]string, len(g.Peers)),
Resources: make([]Resource, len(g.Resources)),
IntegrationReference: g.IntegrationReference,
}
copy(group.Peers, g.Peers)
copy(group.Resources, g.Resources)
return group
}
@ -81,3 +88,26 @@ func (g *Group) RemovePeer(peerID string) bool {
}
return false
}
// AddResource adds resource to Resources if not present, returning true if added.
func (g *Group) AddResource(resource Resource) bool {
for _, item := range g.Resources {
if item == resource {
return false
}
}
g.Resources = append(g.Resources, resource)
return true
}
// RemoveResource removes resource from Resources if present, returning true if removed.
func (g *Group) RemoveResource(resource Resource) bool {
for i, item := range g.Resources {
if item == resource {
g.Resources = append(g.Resources[:i], g.Resources[i+1:]...)
return true
}
}
return false
}

View File

@ -1,4 +1,4 @@
package group
package types
import (
"testing"

View File

@ -13,7 +13,6 @@ import (
"github.com/netbirdio/netbird/management/server/activity"
nbContext "github.com/netbirdio/netbird/management/server/context"
nbgroup "github.com/netbirdio/netbird/management/server/group"
"github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
@ -1143,8 +1142,8 @@ func (am *DefaultAccountManager) prepareUserDeletion(ctx context.Context, accoun
}
// updateUserPeersInGroups updates the user's peers in the specified groups by adding or removing them.
func (am *DefaultAccountManager) updateUserPeersInGroups(accountGroups map[string]*nbgroup.Group, peers []*nbpeer.Peer, groupsToAdd,
groupsToRemove []string) (groupsToUpdate []*nbgroup.Group, err error) {
func (am *DefaultAccountManager) updateUserPeersInGroups(accountGroups map[string]*types.Group, peers []*nbpeer.Peer, groupsToAdd,
groupsToRemove []string) (groupsToUpdate []*types.Group, err error) {
if len(groupsToAdd) == 0 && len(groupsToRemove) == 0 {
return
@ -1177,7 +1176,7 @@ func (am *DefaultAccountManager) updateUserPeersInGroups(accountGroups map[strin
}
// addUserPeersToGroup adds the user's peers to the group.
func addUserPeersToGroup(userPeerIDs map[string]struct{}, group *nbgroup.Group) {
func addUserPeersToGroup(userPeerIDs map[string]struct{}, group *types.Group) {
groupPeers := make(map[string]struct{}, len(group.Peers))
for _, pid := range group.Peers {
groupPeers[pid] = struct{}{}
@ -1194,7 +1193,7 @@ func addUserPeersToGroup(userPeerIDs map[string]struct{}, group *nbgroup.Group)
}
// removeUserPeersFromGroup removes user's peers from the group.
func removeUserPeersFromGroup(userPeerIDs map[string]struct{}, group *nbgroup.Group) {
func removeUserPeersFromGroup(userPeerIDs map[string]struct{}, group *types.Group) {
// skip removing peers from group All
if group.Name == "All" {
return

View File

@ -11,7 +11,6 @@ import (
cacheStore "github.com/eko/gocache/v3/store"
"github.com/google/go-cmp/cmp"
nbgroup "github.com/netbirdio/netbird/management/server/group"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/store"
"github.com/netbirdio/netbird/management/server/types"
@ -1365,7 +1364,7 @@ func TestUserAccountPeersUpdate(t *testing.T) {
// account groups propagation is enabled
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
err := manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
err := manager.SaveGroup(context.Background(), account.Id, userID, &types.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID, peer3.ID},