From 199bf73103856d16111be7b7fce630c332eb7b37 Mon Sep 17 00:00:00 2001 From: Viktor Liu Date: Tue, 5 Mar 2024 09:45:32 +0100 Subject: [PATCH] Remove usage stats (#1665) --- management/server/account.go | 20 --- management/server/file_store.go | 39 ----- management/server/file_store_test.go | 30 ---- management/server/mock_server/account_mock.go | 10 -- management/server/sqlite_store.go | 46 ----- management/server/sqlite_store_test.go | 27 --- management/server/store.go | 2 - management/server/testdata/store_stats.json | 161 ------------------ 8 files changed, 335 deletions(-) delete mode 100644 management/server/testdata/store_stats.json diff --git a/management/server/account.go b/management/server/account.go index 97f054ff2..43cce41dd 100644 --- a/management/server/account.go +++ b/management/server/account.go @@ -72,7 +72,6 @@ type AccountManager interface { CheckUserAccessByJWTGroups(claims jwtclaims.AuthorizationClaims) error GetAccountFromPAT(pat string) (*Account, *User, *PersonalAccessToken, error) DeleteAccount(accountID, userID string) error - GetUsage(ctx context.Context, accountID string, start time.Time, end time.Time) (*AccountUsageStats, error) MarkPATUsed(tokenID string) error GetUser(claims jwtclaims.AuthorizationClaims) (*User, error) ListUsers(accountID string) ([]*User, error) @@ -233,14 +232,6 @@ type Account struct { RulesG []Rule `json:"-" gorm:"-"` } -// AccountUsageStats represents the current usage statistics for an account -type AccountUsageStats struct { - ActiveUsers int64 `json:"active_users"` - TotalUsers int64 `json:"total_users"` - ActivePeers int64 `json:"active_peers"` - TotalPeers int64 `json:"total_peers"` -} - type UserInfo struct { ID string `json:"id"` Email string `json:"email"` @@ -1121,17 +1112,6 @@ func (am *DefaultAccountManager) DeleteAccount(accountID, userID string) error { return nil } -// GetUsage returns the usage stats for the given account. -// This cannot be used to calculate usage stats for a period in the past as it relies on peers' last seen time. -func (am *DefaultAccountManager) GetUsage(ctx context.Context, accountID string, start time.Time, end time.Time) (*AccountUsageStats, error) { - usageStats, err := am.Store.CalculateUsageStats(ctx, accountID, start, end) - if err != nil { - return nil, fmt.Errorf("failed to calculate usage stats: %w", err) - } - - return usageStats, nil -} - // GetAccountByUserOrAccountID looks for an account by user or accountID, if no account is provided and // userID doesn't have an account associated with it, one account is created // domain is used to create a new account if no account is found diff --git a/management/server/file_store.go b/management/server/file_store.go index ad514781f..0228285cb 100644 --- a/management/server/file_store.go +++ b/management/server/file_store.go @@ -1,8 +1,6 @@ package server import ( - "context" - "fmt" "os" "path/filepath" "strings" @@ -664,40 +662,3 @@ func (s *FileStore) Close() error { func (s *FileStore) GetStoreEngine() StoreEngine { return FileStoreEngine } - -// CalculateUsageStats returns the usage stats for an account -// start and end are inclusive. -func (s *FileStore) CalculateUsageStats(_ context.Context, accountID string, start time.Time, end time.Time) (*AccountUsageStats, error) { - s.mux.Lock() - defer s.mux.Unlock() - - account, exists := s.Accounts[accountID] - if !exists { - return nil, fmt.Errorf("account not found") - } - - stats := &AccountUsageStats{ - TotalUsers: 0, - TotalPeers: int64(len(account.Peers)), - } - - for _, user := range account.Users { - if !user.IsServiceUser { - stats.TotalUsers++ - } - } - - activeUsers := make(map[string]bool) - for _, peer := range account.Peers { - lastSeen := peer.Status.LastSeen - if lastSeen.Compare(start) >= 0 && lastSeen.Compare(end) <= 0 { - if _, exists := account.Users[peer.UserID]; exists && !activeUsers[peer.UserID] { - activeUsers[peer.UserID] = true - stats.ActiveUsers++ - } - stats.ActivePeers++ - } - } - - return stats, nil -} diff --git a/management/server/file_store_test.go b/management/server/file_store_test.go index 083a062b6..e0868fb49 100644 --- a/management/server/file_store_test.go +++ b/management/server/file_store_test.go @@ -1,7 +1,6 @@ package server import ( - "context" "crypto/sha256" "net" "path/filepath" @@ -658,32 +657,3 @@ func newStore(t *testing.T) *FileStore { return store } - -func TestFileStore_CalculateUsageStats(t *testing.T) { - storeDir := t.TempDir() - - err := util.CopyFileContents("testdata/store_stats.json", filepath.Join(storeDir, "store.json")) - require.NoError(t, err) - - store, err := NewFileStore(storeDir, nil) - require.NoError(t, err) - - startDate := time.Date(2024, time.February, 1, 0, 0, 0, 0, time.UTC) - endDate := startDate.AddDate(0, 1, 0).Add(-time.Nanosecond) - - stats1, err := store.CalculateUsageStats(context.TODO(), "account-1", startDate, endDate) - require.NoError(t, err) - - assert.Equal(t, int64(2), stats1.ActiveUsers) - assert.Equal(t, int64(4), stats1.TotalUsers) - assert.Equal(t, int64(3), stats1.ActivePeers) - assert.Equal(t, int64(7), stats1.TotalPeers) - - stats2, err := store.CalculateUsageStats(context.TODO(), "account-2", startDate, endDate) - require.NoError(t, err) - - assert.Equal(t, int64(1), stats2.ActiveUsers) - assert.Equal(t, int64(2), stats2.TotalUsers) - assert.Equal(t, int64(1), stats2.ActivePeers) - assert.Equal(t, int64(2), stats2.TotalPeers) -} diff --git a/management/server/mock_server/account_mock.go b/management/server/mock_server/account_mock.go index 848bad2f5..2df5ef086 100644 --- a/management/server/mock_server/account_mock.go +++ b/management/server/mock_server/account_mock.go @@ -1,7 +1,6 @@ package mock_server import ( - "context" "net" "time" @@ -93,7 +92,6 @@ type MockAccountManager struct { SavePostureChecksFunc func(accountID, userID string, postureChecks *posture.Checks) error DeletePostureChecksFunc func(accountID, postureChecksID, userID string) error ListPostureChecksFunc func(accountID, userID string) ([]*posture.Checks, error) - GetUsageFunc func(ctx context.Context, accountID string, start, end time.Time) (*server.AccountUsageStats, error) GetIdpManagerFunc func() idp.Manager } @@ -707,14 +705,6 @@ func (am *MockAccountManager) ListPostureChecks(accountID, userID string) ([]*po return nil, status.Errorf(codes.Unimplemented, "method ListPostureChecks is not implemented") } -// GetUsage mocks GetUsage of the AccountManager interface -func (am *MockAccountManager) GetUsage(ctx context.Context, accountID string, start time.Time, end time.Time) (*server.AccountUsageStats, error) { - if am.GetUsageFunc != nil { - return am.GetUsageFunc(ctx, accountID, start, end) - } - return nil, status.Errorf(codes.Unimplemented, "method GetUsage is not implemented") -} - // GetIdpManager mocks GetIdpManager of the AccountManager interface func (am *MockAccountManager) GetIdpManager() idp.Manager { if am.GetIdpManagerFunc != nil { diff --git a/management/server/sqlite_store.go b/management/server/sqlite_store.go index c12ad1edd..b077acf48 100644 --- a/management/server/sqlite_store.go +++ b/management/server/sqlite_store.go @@ -1,7 +1,6 @@ package server import ( - "context" "fmt" "path/filepath" "runtime" @@ -498,48 +497,3 @@ func (s *SqliteStore) Close() error { func (s *SqliteStore) GetStoreEngine() StoreEngine { return SqliteStoreEngine } - -// CalculateUsageStats returns the usage stats for an account -// start and end are inclusive. -func (s *SqliteStore) CalculateUsageStats(ctx context.Context, accountID string, start time.Time, end time.Time) (*AccountUsageStats, error) { - stats := &AccountUsageStats{} - - err := s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - err := tx.Model(&nbpeer.Peer{}). - Where("account_id = ? AND peer_status_last_seen BETWEEN ? AND ?", accountID, start, end). - Distinct("user_id"). - Count(&stats.ActiveUsers).Error - if err != nil { - return fmt.Errorf("get active users: %w", err) - } - - err = tx.Model(&User{}). - Where("account_id = ? AND is_service_user = ?", accountID, false). - Count(&stats.TotalUsers).Error - if err != nil { - return fmt.Errorf("get total users: %w", err) - } - - err = tx.Model(&nbpeer.Peer{}). - Where("account_id = ? AND peer_status_last_seen BETWEEN ? AND ?", accountID, start, end). - Count(&stats.ActivePeers).Error - if err != nil { - return fmt.Errorf("get active peers: %w", err) - } - - err = tx.Model(&nbpeer.Peer{}). - Where("account_id = ?", accountID). - Count(&stats.TotalPeers).Error - if err != nil { - return fmt.Errorf("get total peers: %w", err) - } - - return nil - }) - - if err != nil { - return nil, fmt.Errorf("transaction: %w", err) - } - - return stats, nil -} diff --git a/management/server/sqlite_store_test.go b/management/server/sqlite_store_test.go index e85ee211f..29b49d7f3 100644 --- a/management/server/sqlite_store_test.go +++ b/management/server/sqlite_store_test.go @@ -1,7 +1,6 @@ package server import ( - "context" "fmt" "net" "path/filepath" @@ -347,29 +346,3 @@ func newAccount(store Store, id int) error { return store.SaveAccount(account) } - -func TestSqliteStore_CalculateUsageStats(t *testing.T) { - store := newSqliteStoreFromFile(t, "testdata/store_stats.json") - t.Cleanup(func() { - require.NoError(t, store.Close()) - }) - - startDate := time.Date(2024, time.February, 1, 0, 0, 0, 0, time.UTC) - endDate := startDate.AddDate(0, 1, 0).Add(-time.Nanosecond) - - stats1, err := store.CalculateUsageStats(context.TODO(), "account-1", startDate, endDate) - require.NoError(t, err) - - assert.Equal(t, int64(2), stats1.ActiveUsers) - assert.Equal(t, int64(4), stats1.TotalUsers) - assert.Equal(t, int64(3), stats1.ActivePeers) - assert.Equal(t, int64(7), stats1.TotalPeers) - - stats2, err := store.CalculateUsageStats(context.TODO(), "account-2", startDate, endDate) - require.NoError(t, err) - - assert.Equal(t, int64(1), stats2.ActiveUsers) - assert.Equal(t, int64(2), stats2.TotalUsers) - assert.Equal(t, int64(1), stats2.ActivePeers) - assert.Equal(t, int64(2), stats2.TotalPeers) -} diff --git a/management/server/store.go b/management/server/store.go index 9a715289d..7ef090a67 100644 --- a/management/server/store.go +++ b/management/server/store.go @@ -1,7 +1,6 @@ package server import ( - "context" "fmt" "os" "path/filepath" @@ -42,7 +41,6 @@ type Store interface { // GetStoreEngine should return StoreEngine of the current store implementation. // This is also a method of metrics.DataSource interface. GetStoreEngine() StoreEngine - CalculateUsageStats(ctx context.Context, accountID string, start time.Time, end time.Time) (*AccountUsageStats, error) } type StoreEngine string diff --git a/management/server/testdata/store_stats.json b/management/server/testdata/store_stats.json deleted file mode 100644 index 747916370..000000000 --- a/management/server/testdata/store_stats.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "Accounts": { - "account-1": { - "Id": "account-1", - "Domain": "example.com", - "Network": { - "Id": "af1c8024-ha40-4ce2-9418-34653101fc3c", - "Net": { - "IP": "100.64.0.0", - "Mask": "//8AAA==" - }, - "Dns": null - }, - "Users": { - "user-1-account-1": { - "Id": "user-1-account-1" - }, - "user-2-account-1": { - "Id": "user-2-account-1" - }, - "user-3-account-1": { - "Id": "user-3-account-1" - }, - "user-4-account-1": { - "Id": "user-4-account-1" - }, - "user-5-account-1": { - "Id": "user-5-account-1", - "IsServiceUser": true - } - }, - "Peers": { - "peer-1-account-1": { - "ID": "peer-1-account-1", - "UserID": "user-1-account-1", - "Status": { - "LastSeen": "2024-01-01T00:00:00Z" - }, - "Name": "Peer One", - "Meta": { - "Hostname": "peer1-host" - } - }, - "peer-2-account-1": { - "ID": "peer-2-account-1", - "UserID": "user-2-account-1", - "Status": { - "LastSeen": "2024-02-29T23:59:59Z" - }, - "Name": "Peer Two", - "Meta": { - "Hostname": "peer2-host" - } - }, - "peer-3-account-1": { - "ID": "peer-3-account-1", - "UserID": "user-2-account-1", - "Status": { - "LastSeen": "2024-02-01T12:00:00Z" - }, - "Name": "Peer Three", - "Meta": { - "Hostname": "peer3-host" - } - }, - "peer-4-account-1": { - "ID": "peer-4-account-1", - "UserID": "user-3-account-1", - "Status": { - "LastSeen": "2024-02-08T12:00:00Z" - }, - "Name": "Peer Four", - "Meta": { - "Hostname": "peer4-host" - } - }, - "peer-5-account-1": { - "ID": "peer-5-account-1", - "UserID": "user-3-account-1", - "Status": { - "LastSeen": "2023-06-01T12:00:00Z" - }, - "Name": "Peer Five", - "Meta": { - "Hostname": "peer5-host" - } - }, - "peer-6-account-1": { - "ID": "peer-6-account-1", - "UserID": "user-4-account-1", - "Status": { - "LastSeen": "2024-01-31T23:59:59Z" - }, - "Name": "Peer Six", - "Meta": { - "Hostname": "peer6-host" - } - }, - "peer-7-account-1": { - "ID": "peer-7-account-1", - "UserID": "user-4-account-1", - "Status": { - "LastSeen": "2024-03-01T00:00:00Z" - }, - "Name": "Peer Seven", - "Meta": { - "Hostname": "peer7-host" - } - } - } - }, - "account-2": { - "Id": "account-2", - "Domain": "example.org", - "Network": { - "Id": "af1c8024-ha40-4ce2-9418-34653101fc3c", - "Net": { - "IP": "100.64.0.0", - "Mask": "//8AAA==" - }, - "Dns": null - }, - "Users": { - "user-1-account-2": { - "Id": "user-1-account-2" - }, - "user-2-account-2": { - "Id": "user-1-account-2" - }, - "user-3-account-2": { - "Id": "user-3-account-2", - "IsServiceUser": true - } - }, - "Peers": { - "peer-1-account-2": { - "ID": "peer-1-account-2", - "UserID": "user-1-account-2", - "Status": { - "LastSeen": "2023-08-30T12:00:00Z" - }, - "Name": "Peer One", - "Meta": { - "Hostname": "peer1-host" - } - }, - "peer-2-account-2": { - "ID": "peer-2-account-2", - "UserID": "user-1-account-2", - "Status": { - "LastSeen": "2024-02-08T12:00:00Z" - }, - "Name": "Peer Two", - "Meta": { - "Hostname": "peer2-host" - } - } - } - } - } -}