cleaned up wire representation of components

Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
This commit is contained in:
Dmitri Dolguikh
2026-07-08 21:29:14 +02:00
parent 7c7dfd7f1d
commit a36a1a3c26
15 changed files with 524 additions and 542 deletions
@@ -29,20 +29,20 @@ func (p NetworkResourceType) String() string {
}
type NetworkResource struct {
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
// AccountSeqID is a per-account monotonically increasing identifier used as the
// compact wire id when sending NetworkMap components to capable peers.
AccountSeqID uint32 `json:"-" gorm:"index:idx_network_resources_account_seq_id;not null;default:0"`
Name string
Description string
Type NetworkResourceType
Address string `gorm:"-"`
GroupIDs []string `gorm:"-"`
Domain string
Prefix netip.Prefix `gorm:"serializer:json"`
Enabled bool
AccountSeqID int32 `json:"-" gorm:"not null;default:0"`
Name string
Description string
Type NetworkResourceType
Address string `gorm:"-"`
GroupIDs []string `gorm:"-"`
Domain string
Prefix netip.Prefix `gorm:"serializer:json"`
Enabled bool
}
func NewNetworkResource(accountID, networkID, name, description, address string, groupIDs []string, enabled bool) (*NetworkResource, error) {
@@ -10,17 +10,17 @@ import (
)
type NetworkRouter struct {
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
// AccountSeqID is a per-account monotonically increasing identifier used as the
// compact wire id when sending NetworkMap components to capable peers.
AccountSeqID uint32 `json:"-" gorm:"index:idx_network_routers_account_seq_id;not null;default:0"`
Peer string
PeerGroups []string `gorm:"serializer:json"`
Masquerade bool
Metric int
Enabled bool
AccountSeqID int32 `json:"-" gorm:"not null;default:0"`
Peer string
PeerGroups []string `gorm:"serializer:json"`
Masquerade bool
Metric int
Enabled bool
}
func NewNetworkRouter(accountID string, networkID string, peer string, peerGroups []string, masquerade bool, metric int, enabled bool) (*NetworkRouter, error) {
+1 -1
View File
@@ -12,7 +12,7 @@ type Network struct {
// AccountSeqID is a per-account monotonically increasing identifier used as the
// compact wire id when sending NetworkMap components to capable peers.
AccountSeqID uint32 `json:"-" gorm:"index:idx_networks_account_seq_id;not null;default:0"`
AccountSeqID int32 `json:"-" gorm:"not null;default:0"`
Name string
Description string
+1 -1
View File
@@ -51,7 +51,7 @@ type Checks struct {
// AccountSeqID is a per-account monotonically increasing identifier used as the
// compact wire id when sending NetworkMap components to capable peers.
AccountSeqID uint32 `json:"-" gorm:"index:idx_posture_checks_account_seq_id;not null;default:0"`
AccountSeqID int32 `json:"-" gorm:"not null;default:0"`
// Checks is a set of objects that perform the actual checks
Checks ChecksDefinition `gorm:"serializer:json"`
+9 -9
View File
@@ -3637,11 +3637,11 @@ func (s *SqlStore) withTx(tx *gorm.DB) Store {
// AllocateAccountSeqID returns the next per-account integer id for the given
// component kind. Must be called inside ExecuteInTransaction so the increment
// is serialized with the component insert.
func (s *SqlStore) AllocateAccountSeqID(ctx context.Context, accountID string, entity types.AccountSeqEntity) (uint32, error) {
func (s *SqlStore) AllocateAccountSeqID(ctx context.Context, accountID string, entity types.AccountSeqEntity) (int32, error) {
return allocateAccountSeqID(ctx, s.db, s.storeEngine, accountID, entity)
}
func allocateAccountSeqID(_ context.Context, db *gorm.DB, engine types.Engine, accountID string, entity types.AccountSeqEntity) (uint32, error) {
func allocateAccountSeqID(_ context.Context, db *gorm.DB, engine types.Engine, accountID string, entity types.AccountSeqEntity) (int32, error) {
switch engine {
case types.PostgresStoreEngine, types.SqliteStoreEngine:
return allocateAccountSeqIDReturning(db, accountID, entity)
@@ -3657,7 +3657,7 @@ func allocateAccountSeqID(_ context.Context, db *gorm.DB, engine types.Engine, a
// SELECT FOR UPDATE. Two concurrent allocations for the same (account, entity)
// produce two distinct ids: one wins the INSERT, the other wins the UPDATE
// branch and returns next_id+1.
func allocateAccountSeqIDReturning(db *gorm.DB, accountID string, entity types.AccountSeqEntity) (uint32, error) {
func allocateAccountSeqIDReturning(db *gorm.DB, accountID string, entity types.AccountSeqEntity) (int32, error) {
const sqlStr = `
INSERT INTO account_seq_counters (account_id, entity, next_id)
VALUES (?, ?, 2)
@@ -3665,7 +3665,7 @@ func allocateAccountSeqIDReturning(db *gorm.DB, accountID string, entity types.A
SET next_id = account_seq_counters.next_id + 1
RETURNING (next_id - 1)
`
var allocated uint32
var allocated int32
if err := db.Raw(sqlStr, accountID, string(entity)).Scan(&allocated).Error; err != nil {
return 0, fmt.Errorf("upsert account seq counter: %w", err)
}
@@ -3682,7 +3682,7 @@ func allocateAccountSeqIDReturning(db *gorm.DB, accountID string, entity types.A
// no-conflict path also surfaces the new next_id, keeping the read-back uniform.
// LAST_INSERT_ID is per-connection; GORM transactions pin a single connection,
// so the follow-up SELECT sees the same value.
func allocateAccountSeqIDMysql(db *gorm.DB, accountID string, entity types.AccountSeqEntity) (uint32, error) {
func allocateAccountSeqIDMysql(db *gorm.DB, accountID string, entity types.AccountSeqEntity) (int32, error) {
const upsertSQL = `
INSERT INTO account_seq_counters (account_id, entity, next_id)
VALUES (?, ?, LAST_INSERT_ID(2))
@@ -3698,7 +3698,7 @@ func allocateAccountSeqIDMysql(db *gorm.DB, accountID string, entity types.Accou
if newNext == 0 {
return 0, fmt.Errorf("LAST_INSERT_ID returned 0; account_seq_counters misconfigured")
}
return uint32(newNext - 1), nil
return int32(newNext - 1), nil
}
// assignAccountSeqIDs allocates a per-account integer id for any component on
@@ -3709,8 +3709,8 @@ func allocateAccountSeqIDMysql(db *gorm.DB, accountID string, entity types.Accou
// per-entity counter is bumped so subsequent AllocateAccountSeqID calls don't
// hand out a colliding id.
func (s *SqlStore) assignAccountSeqIDs(ctx context.Context, tx *gorm.DB, account *types.Account) error {
maxByEntity := make(map[types.AccountSeqEntity]uint32, 8)
bump := func(entity types.AccountSeqEntity, seq uint32) {
maxByEntity := make(map[types.AccountSeqEntity]int32, 8)
bump := func(entity types.AccountSeqEntity, seq int32) {
if seq > maxByEntity[entity] {
maxByEntity[entity] = seq
}
@@ -3856,7 +3856,7 @@ func (s *SqlStore) assignAccountSeqIDs(ctx context.Context, tx *gorm.DB, account
// AccountSeqIDs (e.g. test bulk-load from sqlite to postgres, or migrations
// running before component data lands) so that the next AllocateAccountSeqID
// call returns a fresh id beyond what was just written.
func ensureAccountSeqCounter(db *gorm.DB, engine types.Engine, accountID string, entity types.AccountSeqEntity, target uint32) error {
func ensureAccountSeqCounter(db *gorm.DB, engine types.Engine, accountID string, entity types.AccountSeqEntity, target int32) error {
switch engine {
case types.PostgresStoreEngine, types.SqliteStoreEngine:
const sqlStr = `
+1 -1
View File
@@ -226,7 +226,7 @@ type Store interface {
// AllocateAccountSeqID returns the next per-account integer id for the given
// component kind. Must run inside a transaction so the increment is serialized
// with the component insert.
AllocateAccountSeqID(ctx context.Context, accountID string, entity types.AccountSeqEntity) (uint32, error)
AllocateAccountSeqID(ctx context.Context, accountID string, entity types.AccountSeqEntity) (int32, error)
GetAccountNetworks(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*networkTypes.Network, error)
GetNetworkByID(ctx context.Context, lockStrength LockingStrength, accountID, networkID string) (*networkTypes.Network, error)
@@ -134,8 +134,8 @@ func (a *Account) GetPeerNetworkMapComponents(
NetworkResources: make([]*resourceTypes.NetworkResource, 0),
PostureFailedPeers: make(map[string]map[string]struct{}, len(a.PostureChecks)),
RouterPeers: make(map[string]*nbpeer.Peer),
NetworkXIDToSeq: make(map[string]uint32, len(a.Networks)),
PostureCheckXIDToSeq: make(map[string]uint32, len(a.PostureChecks)),
NetworkXIDToSeq: make(map[string]int32, len(a.Networks)),
PostureCheckXIDToSeq: make(map[string]int32, len(a.PostureChecks)),
}
for _, n := range a.Networks {
if n != nil && n.HasSeqID() {