mirror of
https://github.com/netbirdio/netbird.git
synced 2025-01-10 16:08:14 +01:00
ddc365f7a0
--------- Co-authored-by: Pascal Fischer <32096965+pascal-fischer@users.noreply.github.com> Co-authored-by: bcmmbaga <bethuelmbaga12@gmail.com> Co-authored-by: Maycon Santos <mlsmaycon@gmail.com> Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com>
188 lines
6.5 KiB
Go
188 lines
6.5 KiB
Go
package networks
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/rs/xid"
|
|
|
|
s "github.com/netbirdio/netbird/management/server"
|
|
"github.com/netbirdio/netbird/management/server/activity"
|
|
"github.com/netbirdio/netbird/management/server/networks/resources"
|
|
"github.com/netbirdio/netbird/management/server/networks/routers"
|
|
"github.com/netbirdio/netbird/management/server/networks/types"
|
|
"github.com/netbirdio/netbird/management/server/permissions"
|
|
"github.com/netbirdio/netbird/management/server/status"
|
|
"github.com/netbirdio/netbird/management/server/store"
|
|
)
|
|
|
|
type Manager interface {
|
|
GetAllNetworks(ctx context.Context, accountID, userID string) ([]*types.Network, error)
|
|
CreateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error)
|
|
GetNetwork(ctx context.Context, accountID, userID, networkID string) (*types.Network, error)
|
|
UpdateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error)
|
|
DeleteNetwork(ctx context.Context, accountID, userID, networkID string) error
|
|
}
|
|
|
|
type managerImpl struct {
|
|
store store.Store
|
|
accountManager s.AccountManager
|
|
permissionsManager permissions.Manager
|
|
resourcesManager resources.Manager
|
|
routersManager routers.Manager
|
|
}
|
|
|
|
func NewManager(store store.Store, permissionsManager permissions.Manager, resourceManager resources.Manager, routersManager routers.Manager, accountManager s.AccountManager) Manager {
|
|
return &managerImpl{
|
|
store: store,
|
|
permissionsManager: permissionsManager,
|
|
resourcesManager: resourceManager,
|
|
routersManager: routersManager,
|
|
accountManager: accountManager,
|
|
}
|
|
}
|
|
|
|
func (m *managerImpl) GetAllNetworks(ctx context.Context, accountID, userID string) ([]*types.Network, error) {
|
|
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Read)
|
|
if err != nil {
|
|
return nil, status.NewPermissionValidationError(err)
|
|
}
|
|
if !ok {
|
|
return nil, status.NewPermissionDeniedError()
|
|
}
|
|
|
|
return m.store.GetAccountNetworks(ctx, store.LockingStrengthShare, accountID)
|
|
}
|
|
|
|
func (m *managerImpl) CreateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error) {
|
|
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, network.AccountID, userID, permissions.Networks, permissions.Write)
|
|
if err != nil {
|
|
return nil, status.NewPermissionValidationError(err)
|
|
}
|
|
if !ok {
|
|
return nil, status.NewPermissionDeniedError()
|
|
}
|
|
|
|
network.ID = xid.New().String()
|
|
|
|
unlock := m.store.AcquireWriteLockByUID(ctx, network.AccountID)
|
|
defer unlock()
|
|
|
|
err = m.store.SaveNetwork(ctx, store.LockingStrengthUpdate, network)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to save network: %w", err)
|
|
}
|
|
|
|
m.accountManager.StoreEvent(ctx, userID, network.ID, network.AccountID, activity.NetworkCreated, network.EventMeta())
|
|
|
|
return network, nil
|
|
}
|
|
|
|
func (m *managerImpl) GetNetwork(ctx context.Context, accountID, userID, networkID string) (*types.Network, error) {
|
|
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Read)
|
|
if err != nil {
|
|
return nil, status.NewPermissionValidationError(err)
|
|
}
|
|
if !ok {
|
|
return nil, status.NewPermissionDeniedError()
|
|
}
|
|
|
|
return m.store.GetNetworkByID(ctx, store.LockingStrengthShare, accountID, networkID)
|
|
}
|
|
|
|
func (m *managerImpl) UpdateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error) {
|
|
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, network.AccountID, userID, permissions.Networks, permissions.Write)
|
|
if err != nil {
|
|
return nil, status.NewPermissionValidationError(err)
|
|
}
|
|
if !ok {
|
|
return nil, status.NewPermissionDeniedError()
|
|
}
|
|
|
|
unlock := m.store.AcquireWriteLockByUID(ctx, network.AccountID)
|
|
defer unlock()
|
|
|
|
_, err = m.store.GetNetworkByID(ctx, store.LockingStrengthUpdate, network.AccountID, network.ID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get network: %w", err)
|
|
}
|
|
|
|
m.accountManager.StoreEvent(ctx, userID, network.ID, network.AccountID, activity.NetworkUpdated, network.EventMeta())
|
|
|
|
return network, m.store.SaveNetwork(ctx, store.LockingStrengthUpdate, network)
|
|
}
|
|
|
|
func (m *managerImpl) DeleteNetwork(ctx context.Context, accountID, userID, networkID string) error {
|
|
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Write)
|
|
if err != nil {
|
|
return status.NewPermissionValidationError(err)
|
|
}
|
|
if !ok {
|
|
return status.NewPermissionDeniedError()
|
|
}
|
|
|
|
network, err := m.store.GetNetworkByID(ctx, store.LockingStrengthUpdate, accountID, networkID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get network: %w", err)
|
|
}
|
|
|
|
unlock := m.store.AcquireWriteLockByUID(ctx, accountID)
|
|
defer unlock()
|
|
|
|
var eventsToStore []func()
|
|
err = m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
|
|
resources, err := transaction.GetNetworkResourcesByNetID(ctx, store.LockingStrengthUpdate, accountID, networkID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get resources in network: %w", err)
|
|
}
|
|
|
|
for _, resource := range resources {
|
|
event, err := m.resourcesManager.DeleteResourceInTransaction(ctx, transaction, accountID, userID, networkID, resource.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete resource: %w", err)
|
|
}
|
|
eventsToStore = append(eventsToStore, event...)
|
|
}
|
|
|
|
routers, err := transaction.GetNetworkRoutersByNetID(ctx, store.LockingStrengthUpdate, accountID, networkID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get routers in network: %w", err)
|
|
}
|
|
|
|
for _, router := range routers {
|
|
event, err := m.routersManager.DeleteRouterInTransaction(ctx, transaction, accountID, userID, networkID, router.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete router: %w", err)
|
|
}
|
|
eventsToStore = append(eventsToStore, event)
|
|
}
|
|
|
|
err = transaction.DeleteNetwork(ctx, store.LockingStrengthUpdate, accountID, networkID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete network: %w", err)
|
|
}
|
|
|
|
err = transaction.IncrementNetworkSerial(ctx, store.LockingStrengthUpdate, accountID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to increment network serial: %w", err)
|
|
}
|
|
|
|
eventsToStore = append(eventsToStore, func() {
|
|
m.accountManager.StoreEvent(ctx, userID, networkID, accountID, activity.NetworkDeleted, network.EventMeta())
|
|
})
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete network: %w", err)
|
|
}
|
|
|
|
for _, event := range eventsToStore {
|
|
event()
|
|
}
|
|
|
|
go m.accountManager.UpdateAccountPeers(ctx, accountID)
|
|
|
|
return nil
|
|
}
|