Skip to content

Commit

Permalink
Merge branch 'feature/new-networks-concept' into feature/new-networks…
Browse files Browse the repository at this point in the history
…-concept-api

# Conflicts:
#	management/server/networks/network.go
#	management/server/networks/resources/resource.go
#	management/server/networks/routers/router.go
  • Loading branch information
pascal-fischer committed Dec 11, 2024
2 parents 7b2fe3c + 9f859a2 commit f26737d
Show file tree
Hide file tree
Showing 10 changed files with 674 additions and 0 deletions.
23 changes: 23 additions & 0 deletions management/server/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
cacheStore "github.com/eko/gocache/v3/store"
"github.com/hashicorp/go-multierror"
"github.com/miekg/dns"
"github.com/netbirdio/netbird/management/server/networks"
gocache "github.com/patrickmn/go-cache"
"github.com/rs/xid"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -280,6 +281,10 @@ type Account struct {
PostureChecks []*posture.Checks `gorm:"foreignKey:AccountID;references:id"`
// Settings is a dictionary of Account settings
Settings *Settings `gorm:"embedded;embeddedPrefix:settings_"`

Networks []*networks.Network `gorm:"foreignKey:AccountID;references:id"`
NetworkRouters []*networks.NetworkRouter `gorm:"foreignKey:AccountID;references:id"`
NetworkResources []*networks.NetworkResource `gorm:"foreignKey:AccountID;references:id"`
}

// Subclass used in gorm to only load settings and not whole account
Expand Down Expand Up @@ -883,6 +888,21 @@ func (a *Account) Copy() *Account {
postureChecks = append(postureChecks, postureCheck.Copy())
}

nets := []*networks.Network{}
for _, network := range a.Networks {
nets = append(nets, network.Copy())
}

networkRouters := []*networks.NetworkRouter{}
for _, router := range a.NetworkRouters {
networkRouters = append(networkRouters, router.Copy())
}

networkResources := []*networks.NetworkResource{}
for _, resource := range a.NetworkResources {
networkResources = append(networkResources, resource.Copy())
}

return &Account{
Id: a.Id,
CreatedBy: a.CreatedBy,
Expand All @@ -901,6 +921,9 @@ func (a *Account) Copy() *Account {
DNSSettings: dnsSettings,
PostureChecks: postureChecks,
Settings: settings,
Networks: nets,
NetworkRouters: networkRouters,
NetworkResources: networkResources,
}
}

Expand Down
24 changes: 24 additions & 0 deletions management/server/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"time"

"github.com/golang-jwt/jwt"
"github.com/netbirdio/netbird/management/server/networks"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -1778,6 +1779,29 @@ func TestAccount_Copy(t *testing.T) {
},
},
Settings: &Settings{},
Networks: []*networks.Network{
{
ID: "network1",
},
},
NetworkRouters: []*networks.NetworkRouter{
{
ID: "router1",
NetworkID: "network1",
PeerGroups: []string{"group1"},
Masquerade: false,
Metric: 0,
},
},
NetworkResources: []*networks.NetworkResource{
{
ID: "resource1",
NetworkID: "network1",
Name: "resource",
Type: "Subnet",
Address: "172.12.6.1/24",
},
},
}
err := hasNilField(account)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions management/server/networks/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ func (n *Network) FromAPIRequest(req *api.NetworkRequest) {
n.Name = req.Name
n.Description = *req.Description
}

// Copy returns a copy of a posture checks.
func (n *Network) Copy() *Network {
return &Network{
ID: n.ID,
AccountID: n.AccountID,
Name: n.Name,
Description: n.Description,
}
}
12 changes: 12 additions & 0 deletions management/server/networks/resources/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
n.Address = req.Address
}

func (n *NetworkResource) Copy() *NetworkResource {
return &NetworkResource{
ID: n.ID,
AccountID: n.AccountID,
NetworkID: n.NetworkID,
Name: n.Name,
Description: n.Description,
Type: n.Type,
Address: n.Address,
}
}

// 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 {
Expand Down
12 changes: 12 additions & 0 deletions management/server/networks/routers/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,15 @@ func (n *NetworkRouter) FromAPIRequest(req *api.NetworkRouterRequest) {
n.Masquerade = req.Masquerade
n.Metric = req.Metric
}

func (n *NetworkRouter) Copy() *NetworkRouter {
return &NetworkRouter{
ID: n.ID,
NetworkID: n.NetworkID,
AccountID: n.AccountID,
Peer: n.Peer,
PeerGroups: n.PeerGroups,
Masquerade: n.Masquerade,
Metric: n.Metric,
}
}
158 changes: 158 additions & 0 deletions management/server/sql_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"sync"
"time"

"github.com/netbirdio/netbird/management/server/networks"
log "github.com/sirupsen/logrus"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
Expand Down Expand Up @@ -89,6 +90,7 @@ func NewSqlStore(ctx context.Context, db *gorm.DB, storeEngine StoreEngine, metr
&SetupKey{}, &nbpeer.Peer{}, &User{}, &PersonalAccessToken{}, &nbgroup.Group{},
&Account{}, &Policy{}, &PolicyRule{}, &route.Route{}, &nbdns.NameServerGroup{},
&installation{}, &account.ExtraSettings{}, &posture.Checks{}, &nbpeer.NetworkAddress{},
&networks.Network{}, &networks.NetworkRouter{}, &networks.NetworkResource{},
)
if err != nil {
return nil, fmt.Errorf("auto migrate: %w", err)
Expand Down Expand Up @@ -1597,3 +1599,159 @@ func (s *SqlStore) SaveDNSSettings(ctx context.Context, lockStrength LockingStre

return nil
}

func (s *SqlStore) GetAccountNetworks(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*networks.Network, error) {
var networks []*networks.Network
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Find(&networks, accountIDCondition, accountID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to get networks from the store: %s", result.Error)
return nil, status.Errorf(status.Internal, "failed to get networks from store")
}

return networks, nil
}

func (s *SqlStore) GetNetworkByID(ctx context.Context, lockStrength LockingStrength, accountID, networkID string) (*networks.Network, error) {
var network *networks.Network
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
First(&network, accountAndIDQueryCondition, accountID, networkID)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, status.NewNetworkNotFoundError(networkID)
}

log.WithContext(ctx).Errorf("failed to get network from store: %v", result.Error)
return nil, status.Errorf(status.Internal, "failed to get network from store")
}

return network, nil
}

func (s *SqlStore) SaveNetwork(ctx context.Context, lockStrength LockingStrength, network *networks.Network) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Save(network)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to save network to store: %v", result.Error)
return status.Errorf(status.Internal, "failed to save network to store")
}

return nil
}

func (s *SqlStore) DeleteNetwork(ctx context.Context, lockStrength LockingStrength, accountID, networkID string) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Delete(&networks.Network{}, accountAndIDQueryCondition, accountID, networkID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to delete network from store: %v", result.Error)
return status.Errorf(status.Internal, "failed to delete network from store")
}

if result.RowsAffected == 0 {
return status.NewNetworkNotFoundError(networkID)
}

return nil
}

func (s *SqlStore) GetNetworkRoutersByNetID(ctx context.Context, lockStrength LockingStrength, accountID, netID string) ([]*networks.NetworkRouter, error) {
var netRouters []*networks.NetworkRouter
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Find(&netRouters, "account_id = ? AND network_id = ?", accountID, netID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to get network routers from store: %v", result.Error)
return nil, status.Errorf(status.Internal, "failed to get network routers from store")
}

return netRouters, nil
}

func (s *SqlStore) GetNetworkRouterByID(ctx context.Context, lockStrength LockingStrength, accountID, routerID string) (*networks.NetworkRouter, error) {
var netRouter *networks.NetworkRouter
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
First(&netRouter, accountAndIDQueryCondition, accountID, routerID)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, status.NewNetworkRouterNotFoundError(routerID)
}
log.WithContext(ctx).Errorf("failed to get network router from store: %v", result.Error)
return nil, status.Errorf(status.Internal, "failed to get network router from store")
}

return netRouter, nil
}

func (s *SqlStore) SaveNetworkRouter(ctx context.Context, lockStrength LockingStrength, router *networks.NetworkRouter) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Save(router)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to save network router to store: %v", result.Error)
return status.Errorf(status.Internal, "failed to save network router to store")
}

return nil
}

func (s *SqlStore) DeleteNetworkRouter(ctx context.Context, lockStrength LockingStrength, accountID, routerID string) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Delete(&networks.NetworkRouter{}, accountAndIDQueryCondition, accountID, routerID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to delete network router from store: %v", result.Error)
return status.Errorf(status.Internal, "failed to delete network router from store")
}

if result.RowsAffected == 0 {
return status.NewNetworkRouterNotFoundError(routerID)
}

return nil
}

func (s *SqlStore) GetNetworkResourcesByNetID(ctx context.Context, lockStrength LockingStrength, accountID, networkID string) ([]*networks.NetworkResource, error) {
var netResources []*networks.NetworkResource
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Find(&netResources, "account_id = ? AND network_id = ?", accountID, networkID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to get network resources from store: %v", result.Error)
return nil, status.Errorf(status.Internal, "failed to get network resources from store")
}

return netResources, nil
}

func (s *SqlStore) GetNetworkResourceByID(ctx context.Context, lockStrength LockingStrength, accountID, resourceID string) (*networks.NetworkResource, error) {
var netResources *networks.NetworkResource
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
First(&netResources, accountAndIDQueryCondition, accountID, resourceID)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, status.NewNetworkResourceNotFoundError(resourceID)
}
log.WithContext(ctx).Errorf("failed to get network resource from store: %v", result.Error)
return nil, status.Errorf(status.Internal, "failed to get network resource from store")
}

return netResources, nil
}

func (s *SqlStore) SaveNetworkResource(ctx context.Context, lockStrength LockingStrength, resource *networks.NetworkResource) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).Save(resource)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to save network resource to store: %v", result.Error)
return status.Errorf(status.Internal, "failed to save network resource to store")
}

return nil
}

func (s *SqlStore) DeleteNetworkResource(ctx context.Context, lockStrength LockingStrength, accountID, resourceID string) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Delete(&networks.NetworkResource{}, accountAndIDQueryCondition, accountID, resourceID)
if result.Error != nil {
log.WithContext(ctx).Errorf("failed to delete network resource from store: %v", result.Error)
return status.Errorf(status.Internal, "failed to delete network resource from store")
}

if result.RowsAffected == 0 {
return status.NewNetworkResourceNotFoundError(resourceID)
}

return nil
}
Loading

0 comments on commit f26737d

Please sign in to comment.