Files
netbird/management/server/cache/idp.go
Maycon Santos c02e236196 [client,management] add netflow support to client and update management (#3414)
adds NetFlow functionality to track and log network traffic information between peers, with features including:

- Flow logging for TCP, UDP, and ICMP traffic
- Integration with connection tracking system
- Resource ID tracking in NetFlow events
- DNS and exit node collection configuration
- Flow API and Redis cache in management
- Memory-based flow storage implementation
- Kernel conntrack counters and userspace counters
- TCP state machine improvements for more accurate tracking
- Migration from net.IP to netip.Addr in the userspace firewall
2025-03-20 17:05:48 +01:00

114 lines
3.3 KiB
Go

package cache
import (
"context"
"fmt"
"time"
"github.com/eko/gocache/lib/v4/cache"
"github.com/eko/gocache/lib/v4/marshaler"
"github.com/eko/gocache/lib/v4/store"
"github.com/eko/gocache/store/redis/v4"
"github.com/vmihailenco/msgpack/v5"
"github.com/netbirdio/netbird/management/server/idp"
)
const (
DefaultIDPCacheExpirationMax = 7 * 24 * time.Hour // 7 days
DefaultIDPCacheExpirationMin = 3 * 24 * time.Hour // 3 days
DefaultIDPCacheCleanupInterval = 30 * time.Minute
)
// UserDataCache is an interface that wraps the basic Get, Set and Delete methods for idp.UserData objects.
type UserDataCache interface {
Get(ctx context.Context, key string) (*idp.UserData, error)
Set(ctx context.Context, key string, value *idp.UserData, expiration time.Duration) error
Delete(ctx context.Context, key string) error
}
// UserDataCacheImpl is a struct that implements the UserDataCache interface.
type UserDataCacheImpl struct {
cache Marshaler
}
func (u *UserDataCacheImpl) Get(ctx context.Context, key string) (*idp.UserData, error) {
v, err := u.cache.Get(ctx, key, new(idp.UserData))
if err != nil {
return nil, err
}
data := v.(*idp.UserData)
return data, nil
}
func (u *UserDataCacheImpl) Set(ctx context.Context, key string, value *idp.UserData, expiration time.Duration) error {
return u.cache.Set(ctx, key, value, store.WithExpiration(expiration))
}
func (u *UserDataCacheImpl) Delete(ctx context.Context, key string) error {
return u.cache.Delete(ctx, key)
}
// NewUserDataCache creates a new UserDataCacheImpl object.
func NewUserDataCache(store store.StoreInterface) *UserDataCacheImpl {
simpleCache := cache.New[any](store)
if store.GetType() == redis.RedisType {
m := marshaler.New(simpleCache)
return &UserDataCacheImpl{cache: m}
}
return &UserDataCacheImpl{cache: &marshalerWraper{simpleCache}}
}
// AccountUserDataCache wraps the basic Get, Set and Delete methods for []*idp.UserData objects.
type AccountUserDataCache struct {
cache Marshaler
}
func (a *AccountUserDataCache) Get(ctx context.Context, key string) ([]*idp.UserData, error) {
var m []*idp.UserData
v, err := a.cache.Get(ctx, key, &m)
if err != nil {
return nil, err
}
switch v := v.(type) {
case []*idp.UserData:
return v, nil
case *[]*idp.UserData:
return *v, nil
case []byte:
return unmarshalUserData(v)
}
return nil, fmt.Errorf("unexpected type: %T", v)
}
func unmarshalUserData(data []byte) ([]*idp.UserData, error) {
returnObj := &[]*idp.UserData{}
err := msgpack.Unmarshal(data, returnObj)
if err != nil {
return nil, err
}
return *returnObj, nil
}
func (a *AccountUserDataCache) Set(ctx context.Context, key string, value []*idp.UserData, expiration time.Duration) error {
return a.cache.Set(ctx, key, value, store.WithExpiration(expiration))
}
func (a *AccountUserDataCache) Delete(ctx context.Context, key string) error {
return a.cache.Delete(ctx, key)
}
// NewAccountUserDataCache creates a new AccountUserDataCache object.
func NewAccountUserDataCache(loadableFunc cache.LoadFunction[any], store store.StoreInterface) *AccountUserDataCache {
simpleCache := cache.New[any](store)
loadable := cache.NewLoadable[any](loadableFunc, simpleCache)
if store.GetType() == redis.RedisType {
m := marshaler.New(loadable)
return &AccountUserDataCache{cache: m}
}
return &AccountUserDataCache{cache: &marshalerWraper{loadable}}
}