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

This commit is contained in:
Pascal Fischer
2024-12-12 11:51:44 +01:00
committed by GitHub
parent 7944b8e843
commit d1d6875953
20 changed files with 582 additions and 54 deletions

View File

@@ -3,45 +3,147 @@ package resources
import (
"context"
"errors"
"fmt"
"github.com/netbirdio/netbird/management/server/networks/resources/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 {
GetAllResources(ctx context.Context, accountID, userID, networkID string) ([]*types.NetworkResource, error)
CreateResource(ctx context.Context, accountID string, resource *types.NetworkResource) (*types.NetworkResource, error)
GetAllResourcesInNetwork(ctx context.Context, accountID, userID, networkID string) ([]*types.NetworkResource, error)
GetAllResourcesInAccount(ctx context.Context, accountID, userID string) ([]*types.NetworkResource, error)
GetAllResourceIDsInAccount(ctx context.Context, accountID, userID string) (map[string][]string, error)
CreateResource(ctx context.Context, userID string, resource *types.NetworkResource) (*types.NetworkResource, error)
GetResource(ctx context.Context, accountID, userID, networkID, resourceID string) (*types.NetworkResource, error)
UpdateResource(ctx context.Context, userID string, resource *types.NetworkResource) (*types.NetworkResource, error)
DeleteResource(ctx context.Context, accountID, userID, networkID, resourceID string) error
}
type managerImpl struct {
store store.Store
store store.Store
permissionsManager permissions.Manager
}
func NewManager(store store.Store) Manager {
func NewManager(store store.Store, permissionsManager permissions.Manager) Manager {
return &managerImpl{
store: store,
store: store,
permissionsManager: permissionsManager,
}
}
func (m *managerImpl) GetAllResources(ctx context.Context, accountID, userID, networkID string) ([]*types.NetworkResource, error) {
return nil, errors.New("not implemented")
func (m *managerImpl) GetAllResourcesInNetwork(ctx context.Context, accountID, userID, networkID string) ([]*types.NetworkResource, 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.GetNetworkResourcesByNetID(ctx, store.LockingStrengthShare, accountID, networkID)
}
func (m *managerImpl) CreateResource(ctx context.Context, accountID string, resource *types.NetworkResource) (*types.NetworkResource, error) {
return nil, errors.New("not implemented")
func (m *managerImpl) GetAllResourcesInAccount(ctx context.Context, accountID, userID string) ([]*types.NetworkResource, 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.GetNetworkResourcesByAccountID(ctx, store.LockingStrengthShare, accountID)
}
func (m *managerImpl) GetAllResourceIDsInAccount(ctx context.Context, accountID, userID string) (map[string][]string, 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()
}
resources, err := m.store.GetNetworkResourcesByAccountID(ctx, store.LockingStrengthShare, accountID)
if err != nil {
return nil, fmt.Errorf("failed to get network resources: %w", err)
}
resourceMap := make(map[string][]string)
for _, resource := range resources {
resourceMap[resource.NetworkID] = append(resourceMap[resource.NetworkID], resource.ID)
}
return resourceMap, nil
}
func (m *managerImpl) CreateResource(ctx context.Context, userID string, resource *types.NetworkResource) (*types.NetworkResource, error) {
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, resource.AccountID, userID, permissions.Networks, permissions.Write)
if err != nil {
return nil, status.NewPermissionValidationError(err)
}
if !ok {
return nil, status.NewPermissionDeniedError()
}
resource, err = types.NewNetworkResource(resource.AccountID, resource.NetworkID, resource.Name, resource.Description, resource.Address)
if err != nil {
return nil, fmt.Errorf("failed to create new network resource: %w", err)
}
return resource, m.store.SaveNetworkResource(ctx, store.LockingStrengthUpdate, resource)
}
func (m *managerImpl) GetResource(ctx context.Context, accountID, userID, networkID, resourceID string) (*types.NetworkResource, 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()
}
resource, err := m.store.GetNetworkResourceByID(ctx, store.LockingStrengthShare, accountID, resourceID)
if err != nil {
return nil, fmt.Errorf("failed to get network resource: %w", err)
}
if resource.NetworkID != networkID {
return nil, errors.New("resource not part of network")
}
return resource, nil
}
func (m *managerImpl) UpdateResource(ctx context.Context, userID string, resource *types.NetworkResource) (*types.NetworkResource, error) {
return nil, errors.New("not implemented")
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, resource.AccountID, userID, permissions.Networks, permissions.Write)
if err != nil {
return nil, status.NewPermissionValidationError(err)
}
if !ok {
return nil, status.NewPermissionDeniedError()
}
resourceType, err := types.GetResourceType(resource.Address)
if err != nil {
return nil, fmt.Errorf("failed to get resource type: %w", err)
}
resource.Type = resourceType
return resource, m.store.SaveNetworkResource(ctx, store.LockingStrengthUpdate, resource)
}
func (m *managerImpl) DeleteResource(ctx context.Context, accountID, userID, networkID, resourceID 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.DeleteNetworkResource(ctx, store.LockingStrengthUpdate, accountID, resourceID)
}

View File

@@ -35,7 +35,7 @@ type NetworkResource struct {
}
func NewNetworkResource(accountID, networkID, name, description, address string) (*NetworkResource, error) {
resourceType, err := getResourceType(address)
resourceType, err := GetResourceType(address)
if err != nil {
return nil, fmt.Errorf("invalid address: %w", err)
}
@@ -63,7 +63,7 @@ func (n *NetworkResource) ToAPIResponse() *api.NetworkResource {
func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
n.Name = req.Name
n.Description = ""
if req.Description != nil {
n.Description = *req.Description
}
@@ -82,8 +82,8 @@ func (n *NetworkResource) Copy() *NetworkResource {
}
}
// getResourceType returns the type of the resource based on the address
func getResourceType(address string) (NetworkResourceType, error) {
// GetResourceType returns the type of the resource based on the address
func GetResourceType(address string) (NetworkResourceType, error) {
if ip, cidr, err := net.ParseCIDR(address); err == nil {
ones, _ := cidr.Mask.Size()
if strings.HasSuffix(address, "/32") || (ip != nil && ones == 32) {

View File

@@ -28,7 +28,7 @@ func TestGetResourceType(t *testing.T) {
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
result, err := getResourceType(tt.input)
result, err := GetResourceType(tt.input)
if result != tt.expectedType {
t.Errorf("Expected type %v, got %v", tt.expectedType, result)
}