Fetch Activity events

This commit is contained in:
braginini
2022-12-22 12:06:15 +01:00
parent 647f726737
commit cc12aff3a4
9 changed files with 61 additions and 39 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/miekg/dns" "github.com/miekg/dns"
"github.com/netbirdio/netbird/management/server/event" "github.com/netbirdio/netbird/management/server/activity"
httpapi "github.com/netbirdio/netbird/management/server/http" httpapi "github.com/netbirdio/netbird/management/server/http"
"github.com/netbirdio/netbird/management/server/metrics" "github.com/netbirdio/netbird/management/server/metrics"
"github.com/netbirdio/netbird/management/server/telemetry" "github.com/netbirdio/netbird/management/server/telemetry"
@@ -143,7 +143,7 @@ var (
if disableSingleAccMode { if disableSingleAccMode {
mgmtSingleAccModeDomain = "" mgmtSingleAccModeDomain = ""
} }
eventStore, err := event.NewSQLiteStore(config.Datadir) eventStore, err := activity.NewSQLiteStore(config.Datadir)
if err != nil { if err != nil {
return err return err
} }
+7 -6
View File
@@ -6,7 +6,7 @@ import (
"github.com/eko/gocache/v3/cache" "github.com/eko/gocache/v3/cache"
cacheStore "github.com/eko/gocache/v3/store" cacheStore "github.com/eko/gocache/v3/store"
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/event" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/idp" "github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
@@ -88,6 +88,7 @@ type AccountManager interface {
DeleteNameServerGroup(accountID, nsGroupID string) error DeleteNameServerGroup(accountID, nsGroupID string) error
ListNameServerGroups(accountID string) ([]*nbdns.NameServerGroup, error) ListNameServerGroups(accountID string) ([]*nbdns.NameServerGroup, error)
GetDNSDomain() string GetDNSDomain() string
GetEvents(accountID, userID string) ([]*activity.Event, error)
} }
type DefaultAccountManager struct { type DefaultAccountManager struct {
@@ -100,7 +101,7 @@ type DefaultAccountManager struct {
idpManager idp.Manager idpManager idp.Manager
cacheManager cache.CacheInterface[[]*idp.UserData] cacheManager cache.CacheInterface[[]*idp.UserData]
ctx context.Context ctx context.Context
eventStore event.Store eventStore activity.Store
// singleAccountMode indicates whether the instance has a single account. // singleAccountMode indicates whether the instance has a single account.
// If true, then every new user will end up under the same account. // If true, then every new user will end up under the same account.
@@ -437,7 +438,7 @@ func (a *Account) GetGroupAll() (*Group, error) {
// BuildManager creates a new DefaultAccountManager with a provided Store // BuildManager creates a new DefaultAccountManager with a provided Store
func BuildManager(store Store, peersUpdateManager *PeersUpdateManager, idpManager idp.Manager, func BuildManager(store Store, peersUpdateManager *PeersUpdateManager, idpManager idp.Manager,
singleAccountModeDomain string, dnsDomain string, eventStore event.Store) (*DefaultAccountManager, error) { singleAccountModeDomain string, dnsDomain string, eventStore activity.Store) (*DefaultAccountManager, error) {
am := &DefaultAccountManager{ am := &DefaultAccountManager{
Store: store, Store: store,
peersUpdateManager: peersUpdateManager, peersUpdateManager: peersUpdateManager,
@@ -800,10 +801,10 @@ func (am *DefaultAccountManager) handleNewUserAccount(domainAcc *Account, claims
return nil, err return nil, err
} }
opEvent := event.Event{ opEvent := &activity.Event{
Timestamp: time.Now(), Timestamp: time.Now(),
Type: event.ManagementEvent, Type: activity.ManagementEvent,
OperationCode: event.UserJoinedOperation, OperationCode: activity.UserJoinedOperation,
AccountID: account.Id, AccountID: account.Id,
TargetID: claims.UserId, TargetID: claims.UserId,
ModifierID: claims.UserId, ModifierID: claims.UserId,
@@ -1,4 +1,4 @@
package event package activity
import "time" import "time"
@@ -44,9 +44,9 @@ type Operation int
// Store provides an interface to store or stream events. // Store provides an interface to store or stream events.
type Store interface { type Store interface {
// Save an event in the store // Save an event in the store
Save(event Event) (*Event, error) Save(event *Event) (*Event, error)
// Get returns "limit" number of events from the "offset" index ordered descending or ascending by a timestamp // Get returns "limit" number of events from the "offset" index ordered descending or ascending by a timestamp
Get(accountID string, offset, limit int, descending bool) ([]Event, error) Get(accountID string, offset, limit int, descending bool) ([]*Event, error)
// Close the sink flushing events if necessary // Close the sink flushing events if necessary
Close() error Close() error
} }
@@ -1,4 +1,4 @@
package event package activity
import ( import (
"database/sql" "database/sql"
@@ -19,7 +19,7 @@ const (
" target TEXT);" " target TEXT);"
) )
// SQLiteStore is the implementation of the event.Store interface backed by SQLite // SQLiteStore is the implementation of the activity.Store interface backed by SQLite
type SQLiteStore struct { type SQLiteStore struct {
db *sql.DB db *sql.DB
} }
@@ -40,11 +40,11 @@ func NewSQLiteStore(dataDir string) (*SQLiteStore, error) {
return &SQLiteStore{db: db}, nil return &SQLiteStore{db: db}, nil
} }
func processResult(result *sql.Rows) ([]Event, error) { func processResult(result *sql.Rows) ([]*Event, error) {
events := make([]Event, 0) events := make([]*Event, 0)
for result.Next() { for result.Next() {
var id int64 var id int64
var operation string var operation Operation
var timestamp time.Time var timestamp time.Time
var modifier string var modifier string
var target string var target string
@@ -55,14 +55,15 @@ func processResult(result *sql.Rows) ([]Event, error) {
return nil, err return nil, err
} }
events = append(events, Event{ events = append(events, &Event{
Timestamp: timestamp, Timestamp: timestamp,
Operation: operation, OperationCode: operation,
ID: uint64(id), Operation: MessageForOperation(operation),
Type: typ, ID: uint64(id),
ModifierID: modifier, Type: typ,
TargetID: target, ModifierID: modifier,
AccountID: account, TargetID: target,
AccountID: account,
}) })
} }
@@ -70,7 +71,7 @@ func processResult(result *sql.Rows) ([]Event, error) {
} }
// Get returns "limit" number of events from index ordered descending or ascending by a timestamp // Get returns "limit" number of events from index ordered descending or ascending by a timestamp
func (store *SQLiteStore) Get(accountID string, offset, limit int, descending bool) ([]Event, error) { func (store *SQLiteStore) Get(accountID string, offset, limit int, descending bool) ([]*Event, error) {
order := "DESC" order := "DESC"
if !descending { if !descending {
order = "ASC" order = "ASC"
@@ -91,7 +92,7 @@ func (store *SQLiteStore) Get(accountID string, offset, limit int, descending bo
} }
// Save an event in the SQLite events table // Save an event in the SQLite events table
func (store *SQLiteStore) Save(event Event) (*Event, error) { func (store *SQLiteStore) Save(event *Event) (*Event, error) {
stmt, err := store.db.Prepare("INSERT INTO events(operation, timestamp, modifier, target, account, type) VALUES(?, ?, ?, ?, ?, ?)") stmt, err := store.db.Prepare("INSERT INTO events(operation, timestamp, modifier, target, account, type) VALUES(?, ?, ?, ?, ?, ?)")
if err != nil { if err != nil {
@@ -1,4 +1,4 @@
package event package activity
import ( import (
"fmt" "fmt"
@@ -18,7 +18,7 @@ func TestNewSQLiteStore(t *testing.T) {
accountID := "account_1" accountID := "account_1"
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
_, err = store.Save(Event{ _, err = store.Save(&Event{
Timestamp: time.Now(), Timestamp: time.Now(),
OperationCode: AddPeerByUserOperation, OperationCode: AddPeerByUserOperation,
Type: ManagementEvent, Type: ManagementEvent,
+8
View File
@@ -0,0 +1,8 @@
package server
import "github.com/netbirdio/netbird/management/server/activity"
// GetEvents returns a list of activity events of an account
func (am *DefaultAccountManager) GetEvents(accountID, userID string) ([]*activity.Event, error) {
return am.eventStore.Get(accountID, 0, 1000, true)
}
+15 -6
View File
@@ -3,7 +3,7 @@ package http
import ( import (
"fmt" "fmt"
"github.com/netbirdio/netbird/management/server" "github.com/netbirdio/netbird/management/server"
"github.com/netbirdio/netbird/management/server/event" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/http/api" "github.com/netbirdio/netbird/management/server/http/api"
"github.com/netbirdio/netbird/management/server/http/util" "github.com/netbirdio/netbird/management/server/http/util"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
@@ -30,19 +30,28 @@ func NewEvents(accountManager server.AccountManager, authAudience string) *Event
// GetEvents list of the given account // GetEvents list of the given account
func (h *Events) GetEvents(w http.ResponseWriter, r *http.Request) { func (h *Events) GetEvents(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
_, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
http.Redirect(w, r, "/", http.StatusInternalServerError) http.Redirect(w, r, "/", http.StatusInternalServerError)
return return
} }
var groups []*api.Event accountEvents, err := h.accountManager.GetEvents(account.Id, user.Id)
if err != nil {
util.WriteError(err, w)
return
}
var events []*api.Event
for _, e := range accountEvents {
events = append(events, toEventResponse(e))
}
util.WriteJSONObject(w, groups) util.WriteJSONObject(w, events)
} }
func toEventResponse(event *event.Event) *api.Event { func toEventResponse(event *activity.Event) *api.Event {
return &api.Event{ return &api.Event{
Id: fmt.Sprint(event.ID), Id: fmt.Sprint(event.ID),
InitiatorId: event.ModifierID, InitiatorId: event.ModifierID,
@@ -50,6 +59,6 @@ func toEventResponse(event *event.Event) *api.Event {
OperationCode: int(event.OperationCode), OperationCode: int(event.OperationCode),
TargetId: event.TargetID, TargetId: event.TargetID,
Timestamp: event.Timestamp, Timestamp: event.Timestamp,
Type: event.Type, Type: api.EventType(event.Type),
} }
} }
+3
View File
@@ -40,6 +40,7 @@ func APIHandler(accountManager s.AccountManager, authIssuer string, authAudience
userHandler := NewUserHandler(accountManager, authAudience) userHandler := NewUserHandler(accountManager, authAudience)
routesHandler := NewRoutes(accountManager, authAudience) routesHandler := NewRoutes(accountManager, authAudience)
nameserversHandler := NewNameservers(accountManager, authAudience) nameserversHandler := NewNameservers(accountManager, authAudience)
eventsHandler := NewEvents(accountManager, authAudience)
apiHandler.HandleFunc("/peers", peersHandler.GetPeers).Methods("GET", "OPTIONS") apiHandler.HandleFunc("/peers", peersHandler.GetPeers).Methods("GET", "OPTIONS")
apiHandler.HandleFunc("/peers/{id}", peersHandler.HandlePeer). apiHandler.HandleFunc("/peers/{id}", peersHandler.HandlePeer).
@@ -81,6 +82,8 @@ func APIHandler(accountManager s.AccountManager, authIssuer string, authAudience
apiHandler.HandleFunc("/dns/nameservers/{id}", nameserversHandler.GetNameserverGroupHandler).Methods("GET", "OPTIONS") apiHandler.HandleFunc("/dns/nameservers/{id}", nameserversHandler.GetNameserverGroupHandler).Methods("GET", "OPTIONS")
apiHandler.HandleFunc("/dns/nameservers/{id}", nameserversHandler.DeleteNameserverGroupHandler).Methods("DELETE", "OPTIONS") apiHandler.HandleFunc("/dns/nameservers/{id}", nameserversHandler.DeleteNameserverGroupHandler).Methods("DELETE", "OPTIONS")
apiHandler.HandleFunc("/events", eventsHandler.GetEvents).Methods("GET", "OPTIONS")
err = apiHandler.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { err = apiHandler.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
methods, err := route.GetMethods() methods, err := route.GetMethods()
if err != nil { if err != nil {
+5 -5
View File
@@ -2,7 +2,7 @@ package server
import ( import (
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/event" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"net" "net"
"strings" "strings"
@@ -361,9 +361,9 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
return nil, err return nil, err
} }
opEvent := event.Event{ opEvent := &activity.Event{
Timestamp: time.Now(), Timestamp: time.Now(),
Type: event.ManagementEvent, Type: activity.ManagementEvent,
AccountID: account.Id, AccountID: account.Id,
} }
@@ -380,10 +380,10 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
account.SetupKeys[sk.Key] = sk.IncrementUsage() account.SetupKeys[sk.Key] = sk.IncrementUsage()
opEvent.ModifierID = sk.Id opEvent.ModifierID = sk.Id
opEvent.OperationCode = event.AddPeerWithKeyOperation opEvent.OperationCode = activity.AddPeerWithKeyOperation
} else { } else {
opEvent.ModifierID = userID opEvent.ModifierID = userID
opEvent.OperationCode = event.AddPeerByUserOperation opEvent.OperationCode = activity.AddPeerByUserOperation
} }
takenIps := account.getTakenIPs() takenIps := account.getTakenIPs()