Compare commits

...

5 Commits

10 changed files with 408 additions and 58 deletions

View File

@@ -56,6 +56,7 @@ block.prof: Block profiling information.
heap.prof: Heap profiling information (snapshot of memory allocations). heap.prof: Heap profiling information (snapshot of memory allocations).
allocs.prof: Allocations profiling information. allocs.prof: Allocations profiling information.
threadcreate.prof: Thread creation profiling information. threadcreate.prof: Thread creation profiling information.
stack_trace.txt: Complete stack traces of all goroutines at the time of bundle creation.
Anonymization Process Anonymization Process
@@ -109,6 +110,9 @@ go tool pprof -http=:8088 heap.prof
This will open a web browser tab with the profiling information. This will open a web browser tab with the profiling information.
Stack Trace
The stack_trace.txt file contains a complete snapshot of all goroutine stack traces at the time the debug bundle was created.
Routes Routes
The routes.txt file contains detailed routing table information in a tabular format: The routes.txt file contains detailed routing table information in a tabular format:
@@ -327,6 +331,10 @@ func (g *BundleGenerator) createArchive() error {
log.Errorf("failed to add profiles to debug bundle: %v", err) log.Errorf("failed to add profiles to debug bundle: %v", err)
} }
if err := g.addStackTrace(); err != nil {
log.Errorf("failed to add stack trace to debug bundle: %v", err)
}
if err := g.addSyncResponse(); err != nil { if err := g.addSyncResponse(); err != nil {
return fmt.Errorf("add sync response: %w", err) return fmt.Errorf("add sync response: %w", err)
} }
@@ -522,6 +530,18 @@ func (g *BundleGenerator) addProf() (err error) {
return nil return nil
} }
func (g *BundleGenerator) addStackTrace() error {
buf := make([]byte, 5242880) // 5 MB buffer
n := runtime.Stack(buf, true)
stackTrace := bytes.NewReader(buf[:n])
if err := g.addFileToZip(stackTrace, "stack_trace.txt"); err != nil {
return fmt.Errorf("add stack trace file to zip: %w", err)
}
return nil
}
func (g *BundleGenerator) addInterfaces() error { func (g *BundleGenerator) addInterfaces() error {
interfaces, err := net.Interfaces() interfaces, err := net.Interfaces()
if err != nil { if err != nil {

View File

@@ -20,7 +20,7 @@ type EndpointUpdater struct {
wgConfig WgConfig wgConfig WgConfig
initiator bool initiator bool
// mu protects updateWireGuardPeer and cancelFunc // mu protects cancelFunc
mu sync.Mutex mu sync.Mutex
cancelFunc func() cancelFunc func()
updateWg sync.WaitGroup updateWg sync.WaitGroup
@@ -86,11 +86,9 @@ func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.U
case <-ctx.Done(): case <-ctx.Done():
return return
case <-t.C: case <-t.C:
e.mu.Lock()
if err := e.updateWireGuardPeer(addr, presharedKey); err != nil { if err := e.updateWireGuardPeer(addr, presharedKey); err != nil {
e.log.Errorf("failed to update WireGuard peer, address: %s, error: %v", addr, err) e.log.Errorf("failed to update WireGuard peer, address: %s, error: %v", addr, err)
} }
e.mu.Unlock()
} }
} }

View File

@@ -60,14 +60,7 @@ func (hook ContextHook) Fire(entry *logrus.Entry) error {
entry.Data["context"] = source entry.Data["context"] = source
switch source { addFields(entry)
case HTTPSource:
addHTTPFields(entry)
case GRPCSource:
addGRPCFields(entry)
case SystemSource:
addSystemFields(entry)
}
return nil return nil
} }
@@ -99,7 +92,7 @@ func (hook ContextHook) parseSrc(filePath string) string {
return fmt.Sprintf("%s/%s", pkg, file) return fmt.Sprintf("%s/%s", pkg, file)
} }
func addHTTPFields(entry *logrus.Entry) { func addFields(entry *logrus.Entry) {
if ctxReqID, ok := entry.Context.Value(context.RequestIDKey).(string); ok { if ctxReqID, ok := entry.Context.Value(context.RequestIDKey).(string); ok {
entry.Data[context.RequestIDKey] = ctxReqID entry.Data[context.RequestIDKey] = ctxReqID
} }
@@ -109,30 +102,6 @@ func addHTTPFields(entry *logrus.Entry) {
if ctxInitiatorID, ok := entry.Context.Value(context.UserIDKey).(string); ok { if ctxInitiatorID, ok := entry.Context.Value(context.UserIDKey).(string); ok {
entry.Data[context.UserIDKey] = ctxInitiatorID entry.Data[context.UserIDKey] = ctxInitiatorID
} }
}
func addGRPCFields(entry *logrus.Entry) {
if ctxReqID, ok := entry.Context.Value(context.RequestIDKey).(string); ok {
entry.Data[context.RequestIDKey] = ctxReqID
}
if ctxAccountID, ok := entry.Context.Value(context.AccountIDKey).(string); ok {
entry.Data[context.AccountIDKey] = ctxAccountID
}
if ctxDeviceID, ok := entry.Context.Value(context.PeerIDKey).(string); ok {
entry.Data[context.PeerIDKey] = ctxDeviceID
}
}
func addSystemFields(entry *logrus.Entry) {
if ctxReqID, ok := entry.Context.Value(context.RequestIDKey).(string); ok {
entry.Data[context.RequestIDKey] = ctxReqID
}
if ctxInitiatorID, ok := entry.Context.Value(context.UserIDKey).(string); ok {
entry.Data[context.UserIDKey] = ctxInitiatorID
}
if ctxAccountID, ok := entry.Context.Value(context.AccountIDKey).(string); ok {
entry.Data[context.AccountIDKey] = ctxAccountID
}
if ctxDeviceID, ok := entry.Context.Value(context.PeerIDKey).(string); ok { if ctxDeviceID, ok := entry.Context.Value(context.PeerIDKey).(string); ok {
entry.Data[context.PeerIDKey] = ctxDeviceID entry.Data[context.PeerIDKey] = ctxDeviceID
} }

View File

@@ -144,7 +144,7 @@ func (c *Controller) sendUpdateAccountPeers(ctx context.Context, accountID strin
if c.experimentalNetworkMap(accountID) { if c.experimentalNetworkMap(accountID) {
account = c.getAccountFromHolderOrInit(accountID) account = c.getAccountFromHolderOrInit(accountID)
} else { } else {
account, err = c.requestBuffer.GetAccountWithBackpressure(ctx, accountID) account, err = c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get account: %v", err) return fmt.Errorf("failed to get account: %v", err)
} }
@@ -300,7 +300,7 @@ func (c *Controller) UpdateAccountPeer(ctx context.Context, accountId string, pe
return fmt.Errorf("peer %s doesn't have a channel, skipping network map update", peerId) return fmt.Errorf("peer %s doesn't have a channel, skipping network map update", peerId)
} }
account, err := c.requestBuffer.GetAccountWithBackpressure(ctx, accountId) account, err := c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountId)
if err != nil { if err != nil {
return fmt.Errorf("failed to send out updates to peer %s: %v", peerId, err) return fmt.Errorf("failed to send out updates to peer %s: %v", peerId, err)
} }
@@ -414,7 +414,7 @@ func (c *Controller) GetValidatedPeerWithMap(ctx context.Context, isRequiresAppr
if c.experimentalNetworkMap(accountID) { if c.experimentalNetworkMap(accountID) {
account = c.getAccountFromHolderOrInit(accountID) account = c.getAccountFromHolderOrInit(accountID)
} else { } else {
account, err = c.requestBuffer.GetAccountWithBackpressure(ctx, accountID) account, err = c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountID)
if err != nil { if err != nil {
return nil, nil, nil, 0, err return nil, nil, nil, 0, err
} }
@@ -506,7 +506,7 @@ func (c *Controller) recalculateNetworkMapCache(account *types.Account, validate
func (c *Controller) RecalculateNetworkMapCache(ctx context.Context, accountId string) error { func (c *Controller) RecalculateNetworkMapCache(ctx context.Context, accountId string) error {
if c.experimentalNetworkMap(accountId) { if c.experimentalNetworkMap(accountId) {
account, err := c.requestBuffer.GetAccountWithBackpressure(ctx, accountId) account, err := c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountId)
if err != nil { if err != nil {
return err return err
} }
@@ -548,7 +548,7 @@ func (c *Controller) getAccountFromHolderOrInit(accountID string) *types.Account
if a != nil { if a != nil {
return a return a
} }
account, err := c.holder.LoadOrStoreFunc(accountID, c.requestBuffer.GetAccountWithBackpressure) account, err := c.holder.LoadOrStoreFunc(accountID, c.requestBuffer.GetAccountLightWithBackpressure)
if err != nil { if err != nil {
return nil return nil
} }
@@ -715,7 +715,7 @@ func (c *Controller) OnPeersUpdated(ctx context.Context, accountID string, peerI
func (c *Controller) OnPeersAdded(ctx context.Context, accountID string, peerIDs []string) error { func (c *Controller) OnPeersAdded(ctx context.Context, accountID string, peerIDs []string) error {
for _, peerID := range peerIDs { for _, peerID := range peerIDs {
if c.experimentalNetworkMap(accountID) { if c.experimentalNetworkMap(accountID) {
account, err := c.requestBuffer.GetAccountWithBackpressure(ctx, accountID) account, err := c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountID)
if err != nil { if err != nil {
return err return err
} }
@@ -761,7 +761,7 @@ func (c *Controller) OnPeersDeleted(ctx context.Context, accountID string, peerI
c.peersUpdateManager.CloseChannel(ctx, peerID) c.peersUpdateManager.CloseChannel(ctx, peerID)
if c.experimentalNetworkMap(accountID) { if c.experimentalNetworkMap(accountID) {
account, err := c.requestBuffer.GetAccountWithBackpressure(ctx, accountID) account, err := c.requestBuffer.GetAccountLightWithBackpressure(ctx, accountID)
if err != nil { if err != nil {
log.WithContext(ctx).Errorf("failed to get account %s: %v", accountID, err) log.WithContext(ctx).Errorf("failed to get account %s: %v", accountID, err)
continue continue

View File

@@ -10,9 +10,9 @@ import (
"slices" "slices"
"time" "time"
"github.com/google/uuid"
grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware/v2"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip"
"github.com/rs/xid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@@ -180,7 +180,7 @@ func unaryInterceptor(
info *grpc.UnaryServerInfo, info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler, handler grpc.UnaryHandler,
) (interface{}, error) { ) (interface{}, error) {
reqID := uuid.New().String() reqID := xid.New().String()
//nolint //nolint
ctx = context.WithValue(ctx, hook.ExecutionContextKey, hook.GRPCSource) ctx = context.WithValue(ctx, hook.ExecutionContextKey, hook.GRPCSource)
//nolint //nolint
@@ -194,7 +194,7 @@ func streamInterceptor(
info *grpc.StreamServerInfo, info *grpc.StreamServerInfo,
handler grpc.StreamHandler, handler grpc.StreamHandler,
) error { ) error {
reqID := uuid.New().String() reqID := xid.New().String()
wrapped := grpcMiddleware.WrapServerStream(ss) wrapped := grpcMiddleware.WrapServerStream(ss)
//nolint //nolint
ctx := context.WithValue(ss.Context(), hook.ExecutionContextKey, hook.GRPCSource) ctx := context.WithValue(ss.Context(), hook.ExecutionContextKey, hook.GRPCSource)

View File

@@ -7,5 +7,6 @@ import (
) )
type RequestBuffer interface { type RequestBuffer interface {
GetAccountWithBackpressure(ctx context.Context, accountID string) (*types.Account, error) // GetAccountLightWithBackpressure returns account without users, setup keys, and onboarding data with request buffering
GetAccountLightWithBackpressure(ctx context.Context, accountID string) (*types.Account, error)
} }

View File

@@ -25,11 +25,13 @@ type AccountResult struct {
} }
type AccountRequestBuffer struct { type AccountRequestBuffer struct {
store store.Store store store.Store
getAccountRequests map[string][]*AccountRequest getAccountRequests map[string][]*AccountRequest
mu sync.Mutex getAccountLightRequests map[string][]*AccountRequest
getAccountRequestCh chan *AccountRequest mu sync.Mutex
bufferInterval time.Duration getAccountRequestCh chan *AccountRequest
getAccountLightRequestCh chan *AccountRequest
bufferInterval time.Duration
} }
func NewAccountRequestBuffer(ctx context.Context, store store.Store) *AccountRequestBuffer { func NewAccountRequestBuffer(ctx context.Context, store store.Store) *AccountRequestBuffer {
@@ -45,13 +47,16 @@ func NewAccountRequestBuffer(ctx context.Context, store store.Store) *AccountReq
log.WithContext(ctx).Infof("set account request buffer interval to %s", bufferInterval) log.WithContext(ctx).Infof("set account request buffer interval to %s", bufferInterval)
ac := AccountRequestBuffer{ ac := AccountRequestBuffer{
store: store, store: store,
getAccountRequests: make(map[string][]*AccountRequest), getAccountRequests: make(map[string][]*AccountRequest),
getAccountRequestCh: make(chan *AccountRequest), getAccountLightRequests: make(map[string][]*AccountRequest),
bufferInterval: bufferInterval, getAccountRequestCh: make(chan *AccountRequest),
getAccountLightRequestCh: make(chan *AccountRequest),
bufferInterval: bufferInterval,
} }
go ac.processGetAccountRequests(ctx) go ac.processGetAccountRequests(ctx)
go ac.processGetAccountLightRequests(ctx)
return &ac return &ac
} }
@@ -70,6 +75,22 @@ func (ac *AccountRequestBuffer) GetAccountWithBackpressure(ctx context.Context,
return result.Account, result.Err return result.Account, result.Err
} }
// GetAccountLightWithBackpressure returns account without users, setup keys, and onboarding data with request buffering
func (ac *AccountRequestBuffer) GetAccountLightWithBackpressure(ctx context.Context, accountID string) (*types.Account, error) {
req := &AccountRequest{
AccountID: accountID,
ResultChan: make(chan *AccountResult, 1),
}
log.WithContext(ctx).Tracef("requesting account light %s with backpressure", accountID)
startTime := time.Now()
ac.getAccountLightRequestCh <- req
result := <-req.ResultChan
log.WithContext(ctx).Tracef("got account light with backpressure after %s", time.Since(startTime))
return result.Account, result.Err
}
func (ac *AccountRequestBuffer) processGetAccountBatch(ctx context.Context, accountID string) { func (ac *AccountRequestBuffer) processGetAccountBatch(ctx context.Context, accountID string) {
ac.mu.Lock() ac.mu.Lock()
requests := ac.getAccountRequests[accountID] requests := ac.getAccountRequests[accountID]
@@ -109,3 +130,43 @@ func (ac *AccountRequestBuffer) processGetAccountRequests(ctx context.Context) {
} }
} }
} }
func (ac *AccountRequestBuffer) processGetAccountLightBatch(ctx context.Context, accountID string) {
ac.mu.Lock()
requests := ac.getAccountLightRequests[accountID]
delete(ac.getAccountLightRequests, accountID)
ac.mu.Unlock()
if len(requests) == 0 {
return
}
startTime := time.Now()
account, err := ac.store.GetAccountLight(ctx, accountID)
log.WithContext(ctx).Tracef("getting account light %s in batch took %s", accountID, time.Since(startTime))
result := &AccountResult{Account: account, Err: err}
for _, req := range requests {
req.ResultChan <- result
close(req.ResultChan)
}
}
func (ac *AccountRequestBuffer) processGetAccountLightRequests(ctx context.Context) {
for {
select {
case req := <-ac.getAccountLightRequestCh:
ac.mu.Lock()
ac.getAccountLightRequests[req.AccountID] = append(ac.getAccountLightRequests[req.AccountID], req)
if len(ac.getAccountLightRequests[req.AccountID]) == 1 {
go func(ctx context.Context, accountID string) {
time.Sleep(ac.bufferInterval)
ac.processGetAccountLightBatch(ctx, accountID)
}(ctx, req.AccountID)
}
ac.mu.Unlock()
case <-ctx.Done():
return
}
}
}

View File

@@ -796,6 +796,14 @@ func (s *SqlStore) GetAccount(ctx context.Context, accountID string) (*types.Acc
return s.getAccountGorm(ctx, accountID) return s.getAccountGorm(ctx, accountID)
} }
// GetAccountLight returns account without users, setup keys, and onboarding data
func (s *SqlStore) GetAccountLight(ctx context.Context, accountID string) (*types.Account, error) {
if s.pool != nil {
return s.getAccountLightPgx(ctx, accountID)
}
return s.getAccountLightGorm(ctx, accountID)
}
func (s *SqlStore) getAccountGorm(ctx context.Context, accountID string) (*types.Account, error) { func (s *SqlStore) getAccountGorm(ctx context.Context, accountID string) (*types.Account, error) {
start := time.Now() start := time.Now()
defer func() { defer func() {
@@ -897,6 +905,82 @@ func (s *SqlStore) getAccountGorm(ctx context.Context, accountID string) (*types
return &account, nil return &account, nil
} }
func (s *SqlStore) getAccountLightGorm(ctx context.Context, accountID string) (*types.Account, error) {
start := time.Now()
defer func() {
elapsed := time.Since(start)
if elapsed > 1*time.Second {
log.WithContext(ctx).Tracef("GetAccountLight for account %s exceeded 1s, took: %v", accountID, elapsed)
}
}()
var account types.Account
result := s.db.Model(&account).
Preload("Policies.Rules").
Preload("PeersG").
Preload("GroupsG.GroupPeers").
Preload("RoutesG").
Preload("NameServerGroupsG").
Preload("PostureChecks").
Preload("Networks").
Preload("NetworkRouters").
Preload("NetworkResources").
Take(&account, idQueryCondition, accountID)
if result.Error != nil {
log.WithContext(ctx).Errorf("error when getting account %s from the store: %s", accountID, result.Error)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, status.NewAccountNotFoundError(accountID)
}
return nil, status.NewGetAccountFromStoreError(result.Error)
}
account.SetupKeys = make(map[string]*types.SetupKey)
account.Peers = make(map[string]*nbpeer.Peer, len(account.PeersG))
for _, peer := range account.PeersG {
account.Peers[peer.ID] = &peer
}
account.PeersG = nil
account.Users = make(map[string]*types.User)
account.Groups = make(map[string]*types.Group, len(account.GroupsG))
for _, group := range account.GroupsG {
group.Peers = make([]string, len(group.GroupPeers))
for i, gp := range group.GroupPeers {
group.Peers[i] = gp.PeerID
}
if group.Resources == nil {
group.Resources = []types.Resource{}
}
account.Groups[group.ID] = group
}
account.GroupsG = nil
account.Routes = make(map[route.ID]*route.Route, len(account.RoutesG))
for _, route := range account.RoutesG {
account.Routes[route.ID] = &route
}
account.RoutesG = nil
account.NameServerGroups = make(map[string]*nbdns.NameServerGroup, len(account.NameServerGroupsG))
for _, ns := range account.NameServerGroupsG {
ns.AccountID = ""
if ns.NameServers == nil {
ns.NameServers = []nbdns.NameServer{}
}
if ns.Groups == nil {
ns.Groups = []string{}
}
if ns.Domains == nil {
ns.Domains = []string{}
}
account.NameServerGroups[ns.ID] = &ns
}
account.NameServerGroupsG = nil
account.InitOnce()
return &account, nil
}
func (s *SqlStore) getAccountPgx(ctx context.Context, accountID string) (*types.Account, error) { func (s *SqlStore) getAccountPgx(ctx context.Context, accountID string) (*types.Account, error) {
account, err := s.getAccount(ctx, accountID) account, err := s.getAccount(ctx, accountID)
if err != nil { if err != nil {
@@ -1180,6 +1264,221 @@ func (s *SqlStore) getAccountPgx(ctx context.Context, accountID string) (*types.
return account, nil return account, nil
} }
func (s *SqlStore) getAccountLightPgx(ctx context.Context, accountID string) (*types.Account, error) {
account, err := s.getAccount(ctx, accountID)
if err != nil {
return nil, err
}
var wg sync.WaitGroup
errChan := make(chan error, 9)
wg.Add(1)
go func() {
defer wg.Done()
peers, err := s.getPeers(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.PeersG = peers
}()
wg.Add(1)
go func() {
defer wg.Done()
groups, err := s.getGroups(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.GroupsG = groups
}()
wg.Add(1)
go func() {
defer wg.Done()
policies, err := s.getPolicies(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.Policies = policies
}()
wg.Add(1)
go func() {
defer wg.Done()
routes, err := s.getRoutes(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.RoutesG = routes
}()
wg.Add(1)
go func() {
defer wg.Done()
nsgs, err := s.getNameServerGroups(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.NameServerGroupsG = nsgs
}()
wg.Add(1)
go func() {
defer wg.Done()
checks, err := s.getPostureChecks(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.PostureChecks = checks
}()
wg.Add(1)
go func() {
defer wg.Done()
networks, err := s.getNetworks(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.Networks = networks
}()
wg.Add(1)
go func() {
defer wg.Done()
routers, err := s.getNetworkRouters(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.NetworkRouters = routers
}()
wg.Add(1)
go func() {
defer wg.Done()
resources, err := s.getNetworkResources(ctx, accountID)
if err != nil {
errChan <- err
return
}
account.NetworkResources = resources
}()
wg.Wait()
close(errChan)
for e := range errChan {
if e != nil {
return nil, e
}
}
var policyIDs []string
for _, p := range account.Policies {
policyIDs = append(policyIDs, p.ID)
}
var groupIDs []string
for _, g := range account.GroupsG {
groupIDs = append(groupIDs, g.ID)
}
wg.Add(2)
errChan = make(chan error, 2)
var rules []*types.PolicyRule
go func() {
defer wg.Done()
var err error
rules, err = s.getPolicyRules(ctx, policyIDs)
if err != nil {
errChan <- err
}
}()
var groupPeers []types.GroupPeer
go func() {
defer wg.Done()
var err error
groupPeers, err = s.getGroupPeers(ctx, groupIDs)
if err != nil {
errChan <- err
}
}()
wg.Wait()
close(errChan)
for e := range errChan {
if e != nil {
return nil, e
}
}
rulesByPolicyID := make(map[string][]*types.PolicyRule)
for _, rule := range rules {
rulesByPolicyID[rule.PolicyID] = append(rulesByPolicyID[rule.PolicyID], rule)
}
peersByGroupID := make(map[string][]string)
for _, gp := range groupPeers {
peersByGroupID[gp.GroupID] = append(peersByGroupID[gp.GroupID], gp.PeerID)
}
account.SetupKeys = make(map[string]*types.SetupKey)
account.Peers = make(map[string]*nbpeer.Peer, len(account.PeersG))
for i := range account.PeersG {
peer := &account.PeersG[i]
account.Peers[peer.ID] = peer
}
account.Users = make(map[string]*types.User)
for i := range account.Policies {
policy := account.Policies[i]
if policyRules, ok := rulesByPolicyID[policy.ID]; ok {
policy.Rules = policyRules
}
}
account.Groups = make(map[string]*types.Group, len(account.GroupsG))
for i := range account.GroupsG {
group := account.GroupsG[i]
if peerIDs, ok := peersByGroupID[group.ID]; ok {
group.Peers = peerIDs
}
account.Groups[group.ID] = group
}
account.Routes = make(map[route.ID]*route.Route, len(account.RoutesG))
for i := range account.RoutesG {
route := &account.RoutesG[i]
account.Routes[route.ID] = route
}
account.NameServerGroups = make(map[string]*nbdns.NameServerGroup, len(account.NameServerGroupsG))
for i := range account.NameServerGroupsG {
nsg := &account.NameServerGroupsG[i]
nsg.AccountID = ""
account.NameServerGroups[nsg.ID] = nsg
}
account.SetupKeysG = nil
account.PeersG = nil
account.UsersG = nil
account.GroupsG = nil
account.RoutesG = nil
account.NameServerGroupsG = nil
return account, nil
}
func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Account, error) { func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Account, error) {
var account types.Account var account types.Account
account.Network = &types.Network{} account.Network = &types.Network{}

View File

@@ -51,6 +51,8 @@ type Store interface {
GetAccountsCounter(ctx context.Context) (int64, error) GetAccountsCounter(ctx context.Context) (int64, error)
GetAllAccounts(ctx context.Context) []*types.Account GetAllAccounts(ctx context.Context) []*types.Account
GetAccount(ctx context.Context, accountID string) (*types.Account, error) GetAccount(ctx context.Context, accountID string) (*types.Account, error)
// GetAccountLight returns account without users, setup keys, and onboarding data
GetAccountLight(ctx context.Context, accountID string) (*types.Account, error)
GetAccountMeta(ctx context.Context, lockStrength LockingStrength, accountID string) (*types.AccountMeta, error) GetAccountMeta(ctx context.Context, lockStrength LockingStrength, accountID string) (*types.AccountMeta, error)
GetAccountOnboarding(ctx context.Context, accountID string) (*types.AccountOnboarding, error) GetAccountOnboarding(ctx context.Context, accountID string) (*types.AccountOnboarding, error)
AccountExists(ctx context.Context, lockStrength LockingStrength, id string) (bool, error) AccountExists(ctx context.Context, lockStrength LockingStrength, id string) (bool, error)

View File

@@ -7,8 +7,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/google/uuid"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/rs/xid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
@@ -169,7 +169,7 @@ func (m *HTTPMiddleware) Handler(h http.Handler) http.Handler {
//nolint //nolint
ctx := context.WithValue(r.Context(), hook.ExecutionContextKey, hook.HTTPSource) ctx := context.WithValue(r.Context(), hook.ExecutionContextKey, hook.HTTPSource)
reqID := uuid.New().String() reqID := xid.New().String()
//nolint //nolint
ctx = context.WithValue(ctx, nbContext.RequestIDKey, reqID) ctx = context.WithValue(ctx, nbContext.RequestIDKey, reqID)