mirror of
https://github.com/netbirdio/management-refactor.git
synced 2026-05-22 17:12:59 -07:00
Merge pull request #3 from netbirdio/fetaure/add-networks
Fetaure/add networks
This commit is contained in:
@@ -24,6 +24,7 @@ require (
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
google.golang.org/grpc v1.67.3
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gorm.io/driver/postgres v1.5.11
|
||||
gorm.io/driver/sqlite v1.5.7
|
||||
gorm.io/gorm v1.25.12
|
||||
@@ -166,7 +167,6 @@ require (
|
||||
google.golang.org/api v0.215.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
|
||||
@@ -1,4 +1,35 @@
|
||||
package network_map
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"management/internal/shared/db"
|
||||
appmetrics "management/internal/shared/metrics"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
repo Repository
|
||||
metrics *metrics
|
||||
}
|
||||
|
||||
func NewController(store *db.Store, metrics *appmetrics.AppMetrics) *Controller {
|
||||
cMetrics, err := appmetrics.RegisterMetrics(metrics, newMetrics)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to register app metrics: %v", err)
|
||||
}
|
||||
return &Controller{
|
||||
repo: newRepository(store, cMetrics),
|
||||
metrics: cMetrics,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) UpdatePeers(accountID string) error {
|
||||
data, err := c.repo.GetNetworkMapData(accountID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get network map data: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package network_map
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
)
|
||||
|
||||
type metrics struct {
|
||||
dbAccessDuration metric.Int64Histogram
|
||||
}
|
||||
|
||||
func newMetrics(meter metric.Meter) (*metrics, error) {
|
||||
dbAccessDuration, err := meter.Int64Histogram(
|
||||
"sync_request_duration_seconds",
|
||||
metric.WithDescription("Duration of sync requests in seconds"),
|
||||
metric.WithUnit("s"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &metrics{
|
||||
dbAccessDuration: dbAccessDuration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *metrics) RecordDBAccessDuration(duration time.Duration) {
|
||||
m.dbAccessDuration.Record(context.Background(), duration.Milliseconds(), metric.WithAttributes())
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package network_map
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||
|
||||
"management/internal/modules/accounts"
|
||||
"management/internal/modules/groups"
|
||||
"management/internal/modules/networks"
|
||||
"management/internal/modules/networks/resources"
|
||||
"management/internal/modules/networks/routers"
|
||||
"management/internal/modules/policies"
|
||||
"management/internal/shared/db"
|
||||
)
|
||||
|
||||
type NetworkMapData struct {
|
||||
// we have to name column to aid as it collides with Network.Id when work with associations
|
||||
Id string `gorm:"primaryKey"`
|
||||
|
||||
Domain string `gorm:"index"`
|
||||
DomainCategory string
|
||||
IsDomainPrimaryAccount bool
|
||||
Network *accounts.Network `gorm:"embedded;embeddedPrefix:network_"`
|
||||
Peers []nbpeer.Peer `json:"-" gorm:"foreignKey:AccountID;references:id"`
|
||||
Groups []groups.Group `json:"-" gorm:"foreignKey:AccountID;references:id"`
|
||||
Policies []*policies.Policy `gorm:"foreignKey:AccountID;references:id"`
|
||||
|
||||
Networks []*networks.Network `gorm:"foreignKey:AccountID;references:id"`
|
||||
NetworkRouters []*routers.NetworkRouter `gorm:"foreignKey:AccountID;references:id"`
|
||||
NetworkResources []*resources.NetworkResource `gorm:"foreignKey:AccountID;references:id"`
|
||||
}
|
||||
|
||||
type Repository interface {
|
||||
GetNetworkMapData(accountID string) (*NetworkMapData, error)
|
||||
}
|
||||
|
||||
type repository struct {
|
||||
store *db.Store
|
||||
metrics *metrics
|
||||
}
|
||||
|
||||
func newRepository(s *db.Store, metrics *metrics) Repository {
|
||||
return &repository{
|
||||
store: s,
|
||||
metrics: metrics,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *repository) GetNetworkMapData(accountID string) (*NetworkMapData, error) {
|
||||
start := time.Now()
|
||||
var networkMapData NetworkMapData
|
||||
err := r.store.GetOne(nil, db.LockingStrengthShare, &networkMapData, "id = ?", accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := r.store.Load(&networkMapData, "Peers", "Groups", "Policies", "Networks", "NetworkRouters", "NetworkResources"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.metrics.RecordDBAccessDuration(time.Since(start))
|
||||
|
||||
return &networkMapData, nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package server
|
||||
package network_map
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -15,8 +15,11 @@ import (
|
||||
const channelBufferSize = 100
|
||||
|
||||
type UpdateMessage struct {
|
||||
Update *proto.SyncResponse
|
||||
NetworkMap *types.NetworkMap
|
||||
Update *proto.SyncResponse
|
||||
NetworkMap *types.NetworkMap
|
||||
PeerManager *nbpeer.Manager
|
||||
PolicyManager *nbpeer.PolicyManager
|
||||
GroupManager *nbpeer.GroupManager
|
||||
}
|
||||
|
||||
type UpdateChannel struct {
|
||||
|
||||
@@ -1,10 +1 @@
|
||||
package accounts
|
||||
|
||||
import "management/pkg/logging"
|
||||
|
||||
var log = logging.LoggerForThisPackage()
|
||||
|
||||
type Manager struct {
|
||||
repo Repository
|
||||
handler *handler
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package accounts
|
||||
package manager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -0,0 +1,10 @@
|
||||
package manager
|
||||
|
||||
import "management/pkg/logging"
|
||||
|
||||
var log = logging.LoggerForThisPackage()
|
||||
|
||||
type Manager struct {
|
||||
repo Repository
|
||||
handler *handler
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package accounts
|
||||
package manager
|
||||
|
||||
import "management/internal/shared/db"
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/c-robinson/iplib"
|
||||
"github.com/rs/xid"
|
||||
)
|
||||
|
||||
const (
|
||||
// SubnetSize is a size of the subnet of the global network, e.g. 100.77.0.0/16
|
||||
SubnetSize = 16
|
||||
// NetSize is a global network size 100.64.0.0/10
|
||||
NetSize = 10
|
||||
|
||||
// AllowedIPsFormat generates Wireguard AllowedIPs format (e.g. 100.64.30.1/32)
|
||||
AllowedIPsFormat = "%s/32"
|
||||
)
|
||||
|
||||
type Network struct {
|
||||
Identifier string `json:"id"`
|
||||
Net net.IPNet `gorm:"serializer:json"`
|
||||
Dns string
|
||||
// Serial is an ID that increments by 1 when any change to the network happened (e.g. new peer has been added).
|
||||
// Used to synchronize state to the client apps.
|
||||
Serial uint64
|
||||
|
||||
Mu sync.Mutex `json:"-" gorm:"-"`
|
||||
}
|
||||
|
||||
// NewNetwork creates a new Network initializing it with a Serial=0
|
||||
// It takes a random /16 subnet from 100.64.0.0/10 (64 different subnets)
|
||||
func NewNetwork() *Network {
|
||||
|
||||
n := iplib.NewNet4(net.ParseIP("100.64.0.0"), NetSize)
|
||||
sub, _ := n.Subnet(SubnetSize)
|
||||
|
||||
s := rand.NewSource(time.Now().Unix())
|
||||
r := rand.New(s)
|
||||
intn := r.Intn(len(sub))
|
||||
|
||||
return &Network{
|
||||
Identifier: xid.New().String(),
|
||||
Net: sub[intn].IPNet,
|
||||
Dns: "",
|
||||
Serial: 0}
|
||||
}
|
||||
|
||||
// IncSerial increments Serial by 1 reflecting that the network state has been changed
|
||||
func (n *Network) IncSerial() {
|
||||
n.Mu.Lock()
|
||||
defer n.Mu.Unlock()
|
||||
n.Serial++
|
||||
}
|
||||
|
||||
// CurrentSerial returns the Network.Serial of the network (latest state id)
|
||||
func (n *Network) CurrentSerial() uint64 {
|
||||
n.Mu.Lock()
|
||||
defer n.Mu.Unlock()
|
||||
return n.Serial
|
||||
}
|
||||
|
||||
func (n *Network) Copy() *Network {
|
||||
return &Network{
|
||||
Identifier: n.Identifier,
|
||||
Net: n.Net,
|
||||
Dns: n.Dns,
|
||||
Serial: n.Serial,
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package settings
|
||||
package manager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package settings
|
||||
package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package settings
|
||||
package manager
|
||||
|
||||
import (
|
||||
"management/internal/modules/accounts/settings/types"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package types
|
||||
package settings
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -0,0 +1,25 @@
|
||||
package groups
|
||||
|
||||
import "github.com/netbirdio/netbird/management/server/integration_reference"
|
||||
|
||||
type Group struct {
|
||||
// ID of the group
|
||||
ID string `gorm:"primaryKey"`
|
||||
|
||||
// AccountID is a reference to Account that this object belongs
|
||||
AccountID string `json:"-" gorm:"index"`
|
||||
|
||||
// Name visible in the UI
|
||||
Name string
|
||||
|
||||
// Issued defines how this group was created (enum of "api", "integration" or "jwt")
|
||||
Issued string
|
||||
|
||||
// Peers list of the group
|
||||
Peers []string `gorm:"serializer:json"`
|
||||
|
||||
// Resources contains a list of resources in that group
|
||||
Resources []Resource `gorm:"serializer:json"`
|
||||
|
||||
IntegrationReference integration_reference.IntegrationReference `gorm:"embedded;embeddedPrefix:integration_ref_"`
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package groups
|
||||
package manager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -1,4 +1,4 @@
|
||||
package groups
|
||||
package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package groups
|
||||
package manager
|
||||
|
||||
import (
|
||||
"management/internal/shared/db"
|
||||
@@ -0,0 +1,28 @@
|
||||
package groups
|
||||
|
||||
import "github.com/netbirdio/netbird/management/server/http/api"
|
||||
|
||||
type Resource struct {
|
||||
ID string
|
||||
Type string
|
||||
}
|
||||
|
||||
func (r *Resource) ToAPIResponse() *api.Resource {
|
||||
if r.ID == "" && r.Type == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &api.Resource{
|
||||
Id: r.ID,
|
||||
Type: api.ResourceType(r.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Resource) FromAPIRequest(req *api.Resource) {
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.ID = req.Id
|
||||
r.Type = string(req.Type)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package networks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"management/internal/shared/db"
|
||||
"management/internal/shared/hook"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
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
|
||||
|
||||
// events
|
||||
OnNetworkDelete() *hook.Hook[*NetworkEvent]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user