Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[management] Add managers to link networks API with store #3022

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions management/server/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ import (
"github.com/netbirdio/netbird/management/server/jwtclaims"
"github.com/netbirdio/netbird/management/server/networks"
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/permissions"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/netbirdio/netbird/management/server/settings"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/management/server/store"
"github.com/netbirdio/netbird/management/server/telemetry"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/netbird/management/server/users"
"github.com/netbirdio/netbird/management/server/util"
"github.com/netbirdio/netbird/route"
)
Expand Down Expand Up @@ -149,6 +152,7 @@ type AccountManager interface {
GetAccountSettings(ctx context.Context, accountID string, userID string) (*types.Settings, error)
DeleteSetupKey(ctx context.Context, accountID, userID, keyID string) error
GetNetworksManager() networks.Manager
GetUserManager() users.Manager
}

type DefaultAccountManager struct {
Expand Down Expand Up @@ -186,7 +190,10 @@ type DefaultAccountManager struct {

metrics telemetry.AppMetrics

networksManager networks.Manager
networksManager networks.Manager
userManager users.Manager
settingsManager settings.Manager
permissionsManager permissions.Manager
}

// getJWTGroupsChanges calculates the changes needed to sync a user's JWT groups.
Expand Down Expand Up @@ -253,12 +260,18 @@ func BuildManager(
integratedPeerValidator integrated_validator.IntegratedValidator,
metrics telemetry.AppMetrics,
) (*DefaultAccountManager, error) {
userManager := users.NewManager(store)
settingsManager := settings.NewManager(store)
permissionsManager := permissions.NewManager(userManager, settingsManager)
am := &DefaultAccountManager{
Store: store,
geo: geo,
peersUpdateManager: peersUpdateManager,
idpManager: idpManager,
networksManager: networks.NewManager(store),
networksManager: networks.NewManager(store, permissionsManager),
userManager: userManager,
settingsManager: settingsManager,
permissionsManager: permissionsManager,
ctx: context.Background(),
cacheMux: sync.Mutex{},
cacheLoading: map[string]chan struct{}{},
Expand Down Expand Up @@ -1721,6 +1734,10 @@ func (am *DefaultAccountManager) GetNetworksManager() networks.Manager {
return am.networksManager
}

func (am *DefaultAccountManager) GetUserManager() users.Manager {
return am.userManager
}

// addAllGroup to account object if it doesn't exist
func addAllGroup(account *types.Account) error {
if len(account.Groups) == 0 {
Expand Down
14 changes: 14 additions & 0 deletions management/server/http/api/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1197,8 +1197,22 @@ components:
description: Network ID
type: string
example: chacdk86lnnboviihd7g
routers:
description: List of router IDs associated with the network
type: array
items:
type: string
example: ch8i4ug6lnn4g9hqv7m0
resources:
description: List of network resource IDs associated with the network
type: array
items:
type: string
example: ch8i4ug6lnn4g9hqv7m1
required:
- id
- routers
- resources
- $ref: '#/components/schemas/NetworkRequest'
NetworkResourceRequest:
type: object
Expand Down
6 changes: 6 additions & 0 deletions management/server/http/api/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 53 additions & 4 deletions management/server/http/handlers/networks/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package networks
import (
"context"
"encoding/json"
"fmt"
"net/http"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -59,9 +60,21 @@ func (h *handler) getAllNetworks(w http.ResponseWriter, r *http.Request) {
return
}

routers, err := h.networksManager.GetRouterManager().GetAllRouterIDsInAccount(r.Context(), accountID, userID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

resources, err := h.networksManager.GetResourceManager().GetAllResourceIDsInAccount(r.Context(), accountID, userID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

var networkResponse []*api.Network
for _, network := range networks {
networkResponse = append(networkResponse, network.ToAPIResponse())
networkResponse = append(networkResponse, network.ToAPIResponse(routers[network.ID], resources[network.ID]))
}

util.WriteJSONObject(r.Context(), w, networkResponse)
Expand Down Expand Up @@ -92,7 +105,7 @@ func (h *handler) createNetwork(w http.ResponseWriter, r *http.Request) {
return
}

util.WriteJSONObject(r.Context(), w, network.ToAPIResponse())
util.WriteJSONObject(r.Context(), w, network.ToAPIResponse([]string{}, []string{}))
}

func (h *handler) getNetwork(w http.ResponseWriter, r *http.Request) {
Expand All @@ -116,7 +129,13 @@ func (h *handler) getNetwork(w http.ResponseWriter, r *http.Request) {
return
}

util.WriteJSONObject(r.Context(), w, network.ToAPIResponse())
routerIDs, resourceIDs, err := h.collectIDsInNetwork(r.Context(), accountID, userID, networkID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

util.WriteJSONObject(r.Context(), w, network.ToAPIResponse(routerIDs, resourceIDs))
}

func (h *handler) updateNetwork(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -152,7 +171,13 @@ func (h *handler) updateNetwork(w http.ResponseWriter, r *http.Request) {
return
}

util.WriteJSONObject(r.Context(), w, network.ToAPIResponse())
routerIDs, resourceIDs, err := h.collectIDsInNetwork(r.Context(), accountID, userID, networkID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

util.WriteJSONObject(r.Context(), w, network.ToAPIResponse(routerIDs, resourceIDs))
}

func (h *handler) deleteNetwork(w http.ResponseWriter, r *http.Request) {
Expand All @@ -178,3 +203,27 @@ func (h *handler) deleteNetwork(w http.ResponseWriter, r *http.Request) {

util.WriteJSONObject(r.Context(), w, util.EmptyObject{})
}

func (h *handler) collectIDsInNetwork(ctx context.Context, accountID, userID, networkID string) ([]string, []string, error) {
resources, err := h.networksManager.GetResourceManager().GetAllResourcesInNetwork(ctx, accountID, userID, networkID)
if err != nil {
return nil, nil, fmt.Errorf("failed to get resources in network: %w", err)
}

var resourceIDs []string
for _, resource := range resources {
resourceIDs = append(resourceIDs, resource.ID)
}

routers, err := h.networksManager.GetRouterManager().GetAllRoutersInNetwork(ctx, accountID, userID, networkID)
if err != nil {
return nil, nil, fmt.Errorf("failed to get routers in network: %w", err)
}

var routerIDs []string
for _, router := range routers {
routerIDs = append(routerIDs, router.ID)
}

return routerIDs, resourceIDs, nil
}
28 changes: 25 additions & 3 deletions management/server/http/handlers/networks/resources_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ type resourceHandler struct {

func addResourceEndpoints(resourcesManager resources.Manager, extractFromToken func(ctx context.Context, claims jwtclaims.AuthorizationClaims) (string, string, error), authCfg configs.AuthCfg, router *mux.Router) {
resourceHandler := newResourceHandler(resourcesManager, extractFromToken, authCfg)
router.HandleFunc("/networks/{networkId}/resources", resourceHandler.getAllResources).Methods("GET", "OPTIONS")
router.HandleFunc("/networks/{networkId}/resources", resourceHandler.getAllResourcesInNetwork).Methods("GET", "OPTIONS")
router.HandleFunc("/networks/{networkId}/resources", resourceHandler.createResource).Methods("POST", "OPTIONS")
router.HandleFunc("/networks/{networkId}/resources/{resourceId}", resourceHandler.getResource).Methods("GET", "OPTIONS")
router.HandleFunc("/networks/{networkId}/resources/{resourceId}", resourceHandler.updateResource).Methods("PUT", "OPTIONS")
router.HandleFunc("/networks/{networkId}/resources/{resourceId}", resourceHandler.deleteResource).Methods("DELETE", "OPTIONS")
router.HandleFunc("/networks/resources", resourceHandler.getAllResourcesInAccount).Methods("GET", "OPTIONS")
}

func newResourceHandler(resourceManager resources.Manager, extractFromToken func(ctx context.Context, claims jwtclaims.AuthorizationClaims) (string, string, error), authCfg configs.AuthCfg) *resourceHandler {
Expand All @@ -41,7 +42,7 @@ func newResourceHandler(resourceManager resources.Manager, extractFromToken func
}
}

func (h *resourceHandler) getAllResources(w http.ResponseWriter, r *http.Request) {
func (h *resourceHandler) getAllResourcesInNetwork(w http.ResponseWriter, r *http.Request) {
claims := h.claimsExtractor.FromRequestContext(r)
accountID, userID, err := h.extractFromToken(r.Context(), claims)
if err != nil {
Expand All @@ -50,7 +51,28 @@ func (h *resourceHandler) getAllResources(w http.ResponseWriter, r *http.Request
}

networkID := mux.Vars(r)["networkId"]
resources, err := h.resourceManager.GetAllResources(r.Context(), accountID, userID, networkID)
resources, err := h.resourceManager.GetAllResourcesInNetwork(r.Context(), accountID, userID, networkID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

var resourcesResponse []*api.NetworkResource
for _, resource := range resources {
resourcesResponse = append(resourcesResponse, resource.ToAPIResponse())
}

util.WriteJSONObject(r.Context(), w, resourcesResponse)
}
func (h *resourceHandler) getAllResourcesInAccount(w http.ResponseWriter, r *http.Request) {
claims := h.claimsExtractor.FromRequestContext(r)
accountID, userID, err := h.extractFromToken(r.Context(), claims)
if err != nil {
util.WriteError(r.Context(), err, w)
return
}

resources, err := h.resourceManager.GetAllResourcesInAccount(r.Context(), accountID, userID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (h *routersHandler) getAllRouters(w http.ResponseWriter, r *http.Request) {
}

networkID := mux.Vars(r)["networkId"]
routers, err := h.routersManager.GetAllRouters(r.Context(), accountID, userID, networkID)
routers, err := h.routersManager.GetAllRoutersInNetwork(r.Context(), accountID, userID, networkID)
if err != nil {
util.WriteError(r.Context(), err, w)
return
Expand Down
6 changes: 6 additions & 0 deletions management/server/mock_server/account_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/netbird/management/server/users"
"github.com/netbirdio/netbird/route"
)

Expand Down Expand Up @@ -113,6 +114,11 @@ type MockAccountManager struct {
DeleteSetupKeyFunc func(ctx context.Context, accountID, userID, keyID string) error
}

func (am *MockAccountManager) GetUserManager() users.Manager {
// TODO implement me
panic("implement me")
}

func (am *MockAccountManager) GetNetworksManager() networks.Manager {
// TODO implement me
panic("implement me")
Expand Down
73 changes: 60 additions & 13 deletions management/server/networks/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package networks

import (
"context"
"errors"

"github.com/rs/xid"

"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"
)

Expand All @@ -21,37 +24,81 @@ type Manager interface {
}

type managerImpl struct {
store store.Store
routersManager routers.Manager
resourcesManager resources.Manager
store store.Store
permissionsManager permissions.Manager
routersManager routers.Manager
resourcesManager resources.Manager
}

func NewManager(store store.Store) Manager {
func NewManager(store store.Store, permissionsManager permissions.Manager) Manager {
return &managerImpl{
store: store,
routersManager: routers.NewManager(store),
resourcesManager: resources.NewManager(store),
store: store,
permissionsManager: permissionsManager,
routersManager: routers.NewManager(store, permissionsManager),
resourcesManager: resources.NewManager(store, permissionsManager),
}
}

func (m *managerImpl) GetAllNetworks(ctx context.Context, accountID, userID string) ([]*types.Network, error) {
return nil, errors.New("not implemented")
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) {
return nil, errors.New("not implemented")
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()

return network, m.store.SaveNetwork(ctx, store.LockingStrengthUpdate, network)
}

func (m *managerImpl) GetNetwork(ctx context.Context, accountID, userID, networkID string) (*types.Network, error) {
return nil, errors.New("not implemented")
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) {
return nil, errors.New("not implemented")
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()
}

return network, m.store.SaveNetwork(ctx, store.LockingStrengthUpdate, network)
}

func (m *managerImpl) DeleteNetwork(ctx context.Context, accountID, userID, networkID string) error {
return errors.New("not implemented")
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Write)
if err != nil {
return status.NewPermissionValidationError(err)
}
if !ok {
return status.NewPermissionDeniedError()
}

return m.store.DeleteNetwork(ctx, store.LockingStrengthUpdate, accountID, networkID)
}

func (m *managerImpl) GetResourceManager() resources.Manager {
Expand Down
Loading
Loading