mirror of
https://github.com/netbirdio/management-refactor.git
synced 2026-05-22 17:12:59 -07:00
simplify manager methods
This commit is contained in:
@@ -7,10 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
Using(tx db.Transaction) Manager
|
||||
GetAllNetworks(ctx context.Context, strength db.LockingStrength, accountID, userID string) ([]*Network, error)
|
||||
GetNetwork(ctx context.Context, strength db.LockingStrength, accountID, userID, networkID string) (*Network, error)
|
||||
CreateNetwork(ctx context.Context, userID string, network *Network) (*Network, error)
|
||||
UpdateNetwork(ctx context.Context, userID string, network *Network) (*Network, error)
|
||||
DeleteNetwork(ctx context.Context, accountID, userID, networkID string) error
|
||||
GetAllNetworks(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID, userID string) ([]*Network, error)
|
||||
GetNetwork(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID, userID, networkID string) (*Network, error)
|
||||
CreateNetwork(ctx context.Context, tx db.Transaction, userID string, network *Network) (*Network, error)
|
||||
UpdateNetwork(ctx context.Context, tx db.Transaction, userID string, network *Network) (*Network, error)
|
||||
DeleteNetwork(ctx context.Context, tx db.Transaction, accountID, userID, networkID string) error
|
||||
}
|
||||
|
||||
@@ -1 +1,55 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
nbcontext "github.com/netbirdio/netbird/management/server/context"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
|
||||
"management/internal/modules/networks"
|
||||
"management/internal/shared/errors"
|
||||
"management/internal/shared/permissions"
|
||||
"management/internal/shared/permissions/modules"
|
||||
"management/internal/shared/permissions/operations"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
manager networks.Manager
|
||||
permissionsManager permissions.Manager
|
||||
}
|
||||
|
||||
func newHandler(manager networks.Manager, permissionsManager permissions.Manager) *handler {
|
||||
return &handler{
|
||||
manager: manager,
|
||||
permissionsManager: permissionsManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) RegisterEndpoints(router *mux.Router) {
|
||||
router.HandleFunc("/networks/{id}", h.deleteNetwork).Methods("DELETE", "OPTIONS")
|
||||
}
|
||||
|
||||
func (h *handler) deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
|
||||
if err != nil {
|
||||
util.WriteError(r.Context(), err, w)
|
||||
return
|
||||
}
|
||||
|
||||
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Networks, operations.Write)
|
||||
if err != nil {
|
||||
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
|
||||
return
|
||||
}
|
||||
if !allowed {
|
||||
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
|
||||
}
|
||||
|
||||
err = h.manager.DeleteNetwork(r.Context(), nil, userAuth.AccountId, userAuth.UserId, mux.Vars(r)["id"])
|
||||
if err != nil {
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// _ = json.NewEncoder(w).Encode(users)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/account"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/xid"
|
||||
|
||||
"management/internal/modules/networks"
|
||||
@@ -24,11 +24,16 @@ type managerImpl struct {
|
||||
routersManager routers.Manager
|
||||
}
|
||||
|
||||
func NewManager(store *db.Store, permissionsManager permissions.Manager, resourceManager resources.Manager, routersManager routers.Manager) resources.Manager {
|
||||
func NewManager(store *db.Store, router *mux.Router, permissionsManager permissions.Manager, resourceManager resources.Manager, routersManager routers.Manager) networks.Manager {
|
||||
repo := newRepository(store)
|
||||
m := &managerImpl{repo: repo}
|
||||
// api := newHandler(m, permissionsManager)
|
||||
// api.RegisterEndpoints(router)
|
||||
m := &managerImpl{
|
||||
repo: repo,
|
||||
permissionsManager: permissionsManager,
|
||||
resourcesManager: resourceManager,
|
||||
routersManager: routersManager,
|
||||
}
|
||||
api := newHandler(m, permissionsManager)
|
||||
api.RegisterEndpoints(router)
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -105,41 +110,19 @@ func (m *managerImpl) DeleteNetwork(ctx context.Context, tx db.Transaction, acco
|
||||
return errors.NewPermissionDeniedError()
|
||||
}
|
||||
|
||||
network, err := m.repo.GetNetworkByID(tx, db.LockingStrengthUpdate, accountID, networkID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network: %w", err)
|
||||
}
|
||||
return db.WithTx(m.repo.Store(), tx, func(tx db.Transaction) error {
|
||||
|
||||
resources, err := m.resourcesManager.GetNetworkResourcesByNetID(ctx, tx, db.LockingStrengthUpdate, accountID, userID, networkID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get resources in network: %w", err)
|
||||
}
|
||||
sendEvent(tx, "network_deleted")
|
||||
|
||||
for _, resource := range resources {
|
||||
err = m.resourcesManager.DeleteResource(ctx, tx, accountID, userID, networkID, resource.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete resource: %w", err)
|
||||
if err := m.repo.DeleteNetwork(tx, &networks.Network{ID: networkID}); err != nil {
|
||||
return fmt.Errorf("failed to delete network: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
routers, err := m.routersManager.GetNetworkRoutersByNetID(ctx, tx, db.LockingStrengthUpdate, accountID, userID, networkID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get routers in network: %w", err)
|
||||
}
|
||||
tx.AddEvent(func() {
|
||||
addActivityEvent("Network deleted")
|
||||
// noop
|
||||
})
|
||||
|
||||
for _, router := range routers {
|
||||
err := m.routersManager.DeleteRouter(ctx, tx, accountID, userID, networkID, router.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete router: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = m.repo.DeleteNetwork(tx, &networks.Network{ID: networkID})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete network: %w", err)
|
||||
}
|
||||
|
||||
// TODO: send delete event with network
|
||||
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
RunInTx(fn func(tx db.Transaction) error) error
|
||||
Store() *db.Store
|
||||
CreateNetwork(tx db.Transaction, network *networks.Network) error
|
||||
UpdateNetwork(tx db.Transaction, network *networks.Network) error
|
||||
DeleteNetwork(tx db.Transaction, network *networks.Network) error
|
||||
@@ -55,3 +55,7 @@ func (r *repository) GetAccountNetworks(tx db.Transaction, lockingStrength db.Lo
|
||||
}
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (r *repository) Store() *db.Store {
|
||||
return r.store
|
||||
}
|
||||
|
||||
@@ -9,4 +9,5 @@ import (
|
||||
type Manager interface {
|
||||
DeleteResource(ctx context.Context, tx db.Transaction, accountID, userID, networkID, resourceID string) error
|
||||
GetNetworkResourcesByNetID(ctx context.Context, tx db.Transaction, lockingStrength db.LockingStrength, accountID, userID, networkID string) ([]*NetworkResource, error)
|
||||
DeleteResourcesInNetwork(ctx context.Context, tx db.Transaction, accountID, userID, networkID string) error
|
||||
}
|
||||
|
||||
@@ -1 +1,59 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"management/internal/modules/networks"
|
||||
"management/internal/modules/networks/resources"
|
||||
"management/internal/modules/networks/routers"
|
||||
"management/internal/shared/db"
|
||||
"management/internal/shared/errors"
|
||||
"management/internal/shared/permissions"
|
||||
"management/internal/shared/permissions/modules"
|
||||
"management/internal/shared/permissions/operations"
|
||||
)
|
||||
|
||||
type managerImpl struct {
|
||||
repo Repository
|
||||
permissionsManager permissions.Manager
|
||||
resourcesManager resources.Manager
|
||||
routersManager routers.Manager
|
||||
}
|
||||
|
||||
func NewManager(store *db.Store, router *mux.Router, permissionsManager permissions.Manager, resourceManager resources.Manager, routersManager routers.Manager) resources.Manager {
|
||||
repo := newRepository(store)
|
||||
m := &managerImpl{
|
||||
repo: repo,
|
||||
permissionsManager: permissionsManager,
|
||||
resourcesManager: resourceManager,
|
||||
routersManager: routersManager,
|
||||
}
|
||||
// api := newHandler(m, permissionsManager)
|
||||
// api.RegisterEndpoints(router)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *managerImpl) DeleteResourcesInNetwork(ctx context.Context, tx db.Transaction, accountID, userID, networkID string) error {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Networks, operations.Read)
|
||||
if err != nil {
|
||||
return errors.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return errors.NewPermissionDeniedError()
|
||||
}
|
||||
|
||||
resources, err := m.repo.GetResourcesByNetworkID(tx, db.LockingStrengthUpdate, networkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, resource := range resources {
|
||||
err = m.repo.DeleteResource(tx, resource.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"management/internal/modules/networks"
|
||||
"management/internal/modules/networks/resources"
|
||||
"management/internal/shared/db"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
RunInTx(fn func(tx db.Transaction) error) error
|
||||
Using(tx db.Transaction) Repository
|
||||
CreateNetwork(tx db.Transaction, network *networks.Network) error
|
||||
UpdateNetwork(tx db.Transaction, network *networks.Network) error
|
||||
GetNetworkByID(tx db.Transaction, lockingStrength db.LockingStrength, accountID, networkID string) (*networks.Network, error)
|
||||
GetAccountNetworks(tx db.Transaction, lockingStrength db.LockingStrength, accountID string) ([]*networks.Network, error)
|
||||
Store() *db.Store
|
||||
GetResourcesByNetworkID(tx db.Transaction, strength db.LockingStrength, networkID string) ([]*resources.NetworkResource, error)
|
||||
DeleteResource(tx db.Transaction, resourceID string) error
|
||||
}
|
||||
|
||||
type repository struct {
|
||||
@@ -22,40 +19,19 @@ func newRepository(s *db.Store) Repository {
|
||||
return &repository{store: s}
|
||||
}
|
||||
|
||||
func (r *repository) RunInTx(fn func(tx db.Transaction) error) error {
|
||||
return r.store.RunInTx(fn)
|
||||
func (r *repository) Store() *db.Store {
|
||||
return r.store
|
||||
}
|
||||
|
||||
func (r *repository) Using(tx db.Transaction) Repository {
|
||||
return &repository{store: r.store.Using(tx)}
|
||||
}
|
||||
|
||||
func (r *repository) DeleteNetwork(tx db.Transaction, network *networks.Network) error {
|
||||
return r.store.Create(tx, network)
|
||||
}
|
||||
|
||||
func (r *repository) UpdateNetwork(tx db.Transaction, network *networks.Network) error {
|
||||
return r.store.Update(tx, network)
|
||||
}
|
||||
|
||||
func (r *repository) GetNetworkByID(tx db.Transaction, lockingStrength db.LockingStrength, accountID, networkID string) (*networks.Network, error) {
|
||||
var network networks.Network
|
||||
err := r.store.GetOne(tx, lockingStrength, &network, "account_id = ? AND network_id = ?", accountID, networkID)
|
||||
func (r *repository) GetResourcesByNetworkID(tx db.Transaction, strength db.LockingStrength, networkID string) ([]*resources.NetworkResource, error) {
|
||||
var resources []*resources.NetworkResource
|
||||
err := r.store.GetMany(tx, strength, &resources, "network_id = ?", networkID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &network, nil
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (r *repository) GetAccountNetworks(tx db.Transaction, lockingStrength db.LockingStrength, accountID string) ([]*networks.Network, error) {
|
||||
var networks []*networks.Network
|
||||
err := r.store.GetMany(tx, lockingStrength, &networks, "account_id = ?", accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (r *repository) CreateNetwork(tx db.Transaction, network *networks.Network) error {
|
||||
return r.store.Create(tx, network)
|
||||
func (r *repository) DeleteResource(tx db.Transaction, resourceID string) error {
|
||||
return r.store.Delete(tx, &resources.NetworkResource{ID: resourceID})
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
Using(tx db.Transaction) Manager
|
||||
GetNetworkRoutersByNetID(ctx context.Context, tx db.Transaction, lockingStrength db.LockingStrength, accountID, userID, networkID string) ([]*NetworkRouter, error)
|
||||
DeleteRouter(ctx context.Context, tx db.Transaction, accountID, userID, networkID, routerID string) error
|
||||
DeleteRoutersInNetwork(ctx context.Context, tx db.Transaction, accountID, userID, networkID string) error
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package db
|
||||
|
||||
import "gorm.io/gorm"
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type LockingStrength string
|
||||
|
||||
@@ -16,6 +18,11 @@ type Transaction interface {
|
||||
Commit() error
|
||||
Rollback() error
|
||||
AddEvent(event func())
|
||||
FlushEvents()
|
||||
}
|
||||
|
||||
type TransactionalManager[T any] interface {
|
||||
UsingTx(tx Transaction) T
|
||||
}
|
||||
|
||||
type storeTx struct {
|
||||
@@ -23,28 +30,39 @@ type storeTx struct {
|
||||
events []func()
|
||||
}
|
||||
|
||||
func (t *storeTx) Commit() error {
|
||||
err := t.db.Commit().Error
|
||||
if err != nil {
|
||||
t.commitEvents()
|
||||
func (tx *storeTx) Commit() error {
|
||||
for _, e := range tx.events {
|
||||
e()
|
||||
}
|
||||
return err
|
||||
return tx.db.Commit().Error
|
||||
}
|
||||
|
||||
func (t *storeTx) Rollback() error {
|
||||
return t.db.Rollback().Error
|
||||
func (tx *storeTx) Rollback() error {
|
||||
return tx.db.Rollback().Error
|
||||
}
|
||||
|
||||
func (t *storeTx) AddEvent(event func()) {
|
||||
if t.events == nil {
|
||||
t.events = make([]func(), 0)
|
||||
}
|
||||
t.events = append(t.events, event)
|
||||
func (tx *storeTx) AddEvent(fn func()) {
|
||||
tx.events = append(tx.events, fn)
|
||||
}
|
||||
|
||||
func (t *storeTx) commitEvents() {
|
||||
for _, event := range t.events {
|
||||
event()
|
||||
func (tx *storeTx) FlushEvents() {
|
||||
for _, e := range tx.events {
|
||||
e()
|
||||
}
|
||||
t.events = nil
|
||||
tx.events = nil
|
||||
}
|
||||
|
||||
func WithTx(store *Store, parentTx Transaction, fn func(tx Transaction) error) error {
|
||||
if parentTx != nil {
|
||||
return fn(parentTx)
|
||||
}
|
||||
|
||||
return store.RunInTx(func(tx Transaction) error {
|
||||
if err := fn(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.FlushEvents()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user