diff --git a/cmd/admin/handlers/handlers.go b/cmd/admin/handlers/handlers.go index 0e2dfb8c..ceca782f 100644 --- a/cmd/admin/handlers/handlers.go +++ b/cmd/admin/handlers/handlers.go @@ -28,7 +28,7 @@ type HandlersAdmin struct { DB *gorm.DB Users *users.UserManager Tags *tags.TagManager - Envs *environments.Environment + Envs *environments.EnvManager Nodes *nodes.NodeManager Queries *queries.Queries Carves *carves.Carves @@ -55,7 +55,7 @@ func WithDB(db *gorm.DB) HandlersOption { } } -func WithEnvs(envs *environments.Environment) HandlersOption { +func WithEnvs(envs *environments.EnvManager) HandlersOption { return func(h *HandlersAdmin) { h.Envs = envs } diff --git a/cmd/admin/main.go b/cmd/admin/main.go index 7a51004e..a7647037 100644 --- a/cmd/admin/main.go +++ b/cmd/admin/main.go @@ -83,7 +83,7 @@ var ( queriesmgr *queries.Queries carvesmgr *carves.Carves sessionsmgr *sessions.SessionManager - envs *environments.Environment + envs *environments.EnvManager adminUsers *users.UserManager tagsmgr *tags.TagManager carvers3 *carves.CarverS3 diff --git a/cmd/api/handlers/handlers.go b/cmd/api/handlers/handlers.go index 49ee59a2..73239a9d 100644 --- a/cmd/api/handlers/handlers.go +++ b/cmd/api/handlers/handlers.go @@ -23,7 +23,7 @@ type HandlersApi struct { DB *gorm.DB Users *users.UserManager Tags *tags.TagManager - Envs *environments.Environment + Envs *environments.EnvManager Nodes *nodes.NodeManager Queries *queries.Queries Carves *carves.Carves @@ -56,7 +56,7 @@ func WithTags(tags *tags.TagManager) HandlersOption { } } -func WithEnvs(envs *environments.Environment) HandlersOption { +func WithEnvs(envs *environments.EnvManager) HandlersOption { return func(h *HandlersApi) { h.Envs = envs } diff --git a/cmd/api/main.go b/cmd/api/main.go index 17dd8f6e..5af7ef61 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -86,7 +86,7 @@ var ( apiUsers *users.UserManager tagsmgr *tags.TagManager settingsmgr *settings.Settings - envs *environments.Environment + envs *environments.EnvManager nodesmgr *nodes.NodeManager queriesmgr *queries.Queries filecarves *carves.Carves diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 93f1bd15..226b78a2 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -56,7 +56,7 @@ var ( filecarves *carves.Carves adminUsers *users.UserManager tagsmgr *tags.TagManager - envs *environments.Environment + envs *environments.EnvManager db *backend.DBManager osctrlAPI *OsctrlAPI formats map[string]bool diff --git a/cmd/tls/handlers/handlers.go b/cmd/tls/handlers/handlers.go index da3701ff..0a096184 100644 --- a/cmd/tls/handlers/handlers.go +++ b/cmd/tls/handlers/handlers.go @@ -48,8 +48,9 @@ var validPlatform = map[string]bool{ // HandlersTLS to keep all handlers for TLS type HandlersTLS struct { - Envs *environments.Environment + Envs *environments.EnvManager EnvsMap *environments.MapEnvironments + EnvCache *environments.EnvCache Nodes *nodes.NodeManager Tags *tags.TagManager Queries *queries.Queries @@ -71,7 +72,7 @@ type TLSResponse struct { type Option func(*HandlersTLS) // WithEnvs to pass value as option -func WithEnvs(envs *environments.Environment) Option { +func WithEnvs(envs *environments.EnvManager) Option { return func(h *HandlersTLS) { h.Envs = envs } @@ -167,7 +168,7 @@ func CreateHandlersTLS(opts ...Option) *HandlersTLS { for _, opt := range opts { opt(h) } - // All these opt function need be refactored to reduce unnecessary complexity + h.EnvCache = environments.NewEnvCache(*h.Envs) return h } diff --git a/cmd/tls/handlers/post.go b/cmd/tls/handlers/post.go index 9347f2f3..a1a53067 100644 --- a/cmd/tls/handlers/post.go +++ b/cmd/tls/handlers/post.go @@ -2,6 +2,7 @@ package handlers import ( "compress/gzip" + "context" "encoding/json" "fmt" "io" @@ -34,7 +35,7 @@ func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { return } // Get environment - env, err := h.Envs.GetByUUID(envVar) + env, err := h.EnvCache.GetByUUID(context.TODO(), envVar) if err != nil { log.Err(err).Msg("error getting environment") utils.HTTPResponse(w, "", http.StatusInternalServerError, []byte("")) @@ -107,6 +108,7 @@ func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { // ConfigHandler - Function to handle the configuration requests from osquery nodes func (h *HandlersTLS) ConfigHandler(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() var response interface{} // Retrieve environment variable envVar := r.PathValue("env") @@ -120,7 +122,7 @@ func (h *HandlersTLS) ConfigHandler(w http.ResponseWriter, r *http.Request) { return } // Get environment - env, err := h.Envs.GetByUUID(envVar) + env, err := h.EnvCache.GetByUUID(ctx, envVar) if err != nil { log.Err(err).Msg("error getting environment") return @@ -184,7 +186,7 @@ func (h *HandlersTLS) LogHandler(w http.ResponseWriter, r *http.Request) { return } // Get environment - env, err := h.Envs.GetByUUID(envVar) + env, err := h.EnvCache.GetByUUID(context.TODO(), envVar) if err != nil { log.Err(err).Msg("error getting environment") utils.HTTPResponse(w, "", http.StatusInternalServerError, []byte("")) @@ -272,7 +274,7 @@ func (h *HandlersTLS) QueryReadHandler(w http.ResponseWriter, r *http.Request) { return } // Get environment - env, err := h.Envs.GetByUUID(envVar) + env, err := h.EnvCache.GetByUUID(context.TODO(), envVar) if err != nil { log.Err(err).Msg("error getting environment") utils.HTTPResponse(w, "", http.StatusInternalServerError, []byte("")) @@ -350,7 +352,7 @@ func (h *HandlersTLS) QueryWriteHandler(w http.ResponseWriter, r *http.Request) return } // Get environment - env, err := h.Envs.GetByUUID(envVar) + env, err := h.EnvCache.GetByUUID(context.TODO(), envVar) if err != nil { log.Err(err).Msg("error getting environment") utils.HTTPResponse(w, "", http.StatusInternalServerError, []byte("")) diff --git a/cmd/tls/main.go b/cmd/tls/main.go index d849bdd1..782ea91e 100644 --- a/cmd/tls/main.go +++ b/cmd/tls/main.go @@ -59,7 +59,7 @@ var ( db *backend.DBManager redis *cache.RedisManager settingsmgr *settings.Settings - envs *environments.Environment + envs *environments.EnvManager envsmap environments.MapEnvironments settingsmap settings.MapSettings nodesmgr *nodes.NodeManager @@ -242,6 +242,7 @@ func osctrlService() { log.Info().Msg("Metrics are enabled") // Register Prometheus metrics handlers.RegisterMetrics(prometheus.DefaultRegisterer) + cache.RegisterMetrics(prometheus.DefaultRegisterer) // Creating a new prometheus service prometheusServer := http.NewServeMux() prometheusServer.Handle("/metrics", promhttp.Handler()) @@ -268,7 +269,6 @@ func osctrlService() { handlers.WithWriteHandler(tlsWriter), handlers.WithDebugHTTP(&flagParams.DebugHTTPValues), ) - // ///////////////////////// ALL CONTENT IS UNAUTHENTICATED FOR TLS log.Info().Msg("Initializing router") // Create router for TLS endpoint diff --git a/pkg/cache/in-memory.go b/pkg/cache/in-memory.go new file mode 100644 index 00000000..c1d9dc00 --- /dev/null +++ b/pkg/cache/in-memory.go @@ -0,0 +1,194 @@ +package cache + +import ( + "context" + "sync" + "time" +) + +// Item represents a cached item with expiration +type Item[T any] struct { + Value T + Expiration int64 +} + +// Cache interface defines methods that any cache implementation must provide +type Cache[T any] interface { + // Get retrieves an item from the cache by key + Get(ctx context.Context, key string) (T, bool) + + // Set adds or updates an item in the cache with expiration + Set(ctx context.Context, key string, value T, duration time.Duration) + + // Delete removes an item from the cache + Delete(ctx context.Context, key string) + + // Clear removes all items from the cache + Clear(ctx context.Context) + + // ItemCount returns the number of items in the cache + ItemCount() int + + // Stop stops the cleanup goroutine + Stop() +} + +// MemoryCacheOption is a function that configures a MemoryCache +type MemoryCacheOption[T any] func(*MemoryCache[T]) + +// WithCleanupInterval sets the interval for cleaning expired items +func WithCleanupInterval[T any](interval time.Duration) MemoryCacheOption[T] { + return func(mc *MemoryCache[T]) { + mc.cleanupInterval = interval + } +} + +// WithName sets the name for the cache instance +func WithName[T any](name string) MemoryCacheOption[T] { + return func(mc *MemoryCache[T]) { + mc.name = name + } +} + +// MemoryCache provides an in-memory implementation of the Cache interface +type MemoryCache[T any] struct { + items map[string]Item[T] + mutex sync.RWMutex + cleanupInterval time.Duration + stopCleanup chan struct{} + name string +} + +// NewMemoryCache creates a new in-memory cache with the provided options +func NewMemoryCache[T any](opts ...MemoryCacheOption[T]) *MemoryCache[T] { + cache := &MemoryCache[T]{ + items: make(map[string]Item[T]), + cleanupInterval: 5 * time.Minute, + stopCleanup: make(chan struct{}), + name: "default", + } + + // Apply all provided options + for _, opt := range opts { + opt(cache) + } + + CacheItems.WithLabelValues(cache.name).Set(0) + + // Start cleanup routine to remove expired items + go cache.cleanupRoutine() + + return cache +} + +// Get retrieves an item from the cache +func (c *MemoryCache[T]) Get(ctx context.Context, key string) (T, bool) { + c.mutex.RLock() + defer c.mutex.RUnlock() + + item, found := c.items[key] + if !found { + CacheMisses.WithLabelValues(c.name).Inc() + var zero T + return zero, false + } + + // Check if item has expired + if item.Expiration > 0 && item.Expiration < time.Now().UnixNano() { + CacheMisses.WithLabelValues(c.name).Inc() + var zero T + return zero, false + } + + CacheHits.WithLabelValues(c.name).Inc() + return item.Value, true +} + +// Set adds an item to the cache with expiration +func (c *MemoryCache[T]) Set(ctx context.Context, key string, value T, duration time.Duration) { + var expiration int64 + + if duration > 0 { + expiration = time.Now().Add(duration).UnixNano() + } + + c.mutex.Lock() + defer c.mutex.Unlock() + + c.items[key] = Item[T]{ + Value: value, + Expiration: expiration, + } + + CacheItems.WithLabelValues(c.name).Set(float64(len(c.items))) +} + +// Delete removes an item from the cache +func (c *MemoryCache[T]) Delete(ctx context.Context, key string) { + c.mutex.Lock() + defer c.mutex.Unlock() + + delete(c.items, key) + + CacheItems.WithLabelValues(c.name).Set(float64(len(c.items))) +} + +// Clear removes all items from the cache +func (c *MemoryCache[T]) Clear(ctx context.Context) { + c.mutex.Lock() + defer c.mutex.Unlock() + + c.items = make(map[string]Item[T]) + + CacheItems.WithLabelValues(c.name).Set(0) +} + +// ItemCount returns the number of items in the cache +func (c *MemoryCache[T]) ItemCount() int { + c.mutex.RLock() + defer c.mutex.RUnlock() + + return len(c.items) +} + +// Stop stops the cleanup goroutine +func (c *MemoryCache[T]) Stop() { + close(c.stopCleanup) +} + +// cleanupRoutine periodically cleans up expired items +func (c *MemoryCache[T]) cleanupRoutine() { + ticker := time.NewTicker(c.cleanupInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + c.deleteExpired() + case <-c.stopCleanup: + return + } + } +} + +// deleteExpired removes expired items from the cache +func (c *MemoryCache[T]) deleteExpired() { + now := time.Now().UnixNano() + + c.mutex.Lock() + defer c.mutex.Unlock() + + evictionCount := 0 + for k, v := range c.items { + if v.Expiration > 0 && v.Expiration < now { + delete(c.items, k) + evictionCount++ + } + } + + if evictionCount > 0 { + // Update Prometheus metrics for evictions and item count + CacheEvictions.WithLabelValues(c.name).Add(float64(evictionCount)) + CacheItems.WithLabelValues(c.name).Set(float64(len(c.items))) + } +} diff --git a/pkg/cache/in-memory_test.go b/pkg/cache/in-memory_test.go new file mode 100644 index 00000000..029532c6 --- /dev/null +++ b/pkg/cache/in-memory_test.go @@ -0,0 +1,182 @@ +package cache + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMemoryCache_SetAndGet(t *testing.T) { + cache := NewMemoryCache[string]() + defer cache.Stop() + + ctx := context.Background() + + // Test setting and getting a value + cache.Set(ctx, "key1", "value1", 0) + value, found := cache.Get(ctx, "key1") + assert.True(t, found, "Expected to find the key") + assert.Equal(t, "value1", value, "Expected value to match") + + // Test getting a non-existent key + _, found = cache.Get(ctx, "nonexistent") + assert.False(t, found, "Expected not to find the key") +} + +func TestMemoryCache_Expiration(t *testing.T) { + cache := NewMemoryCache[string]() + defer cache.Stop() + + ctx := context.Background() + + // Set a value with a short expiration + cache.Set(ctx, "key1", "value1", 50*time.Millisecond) + value, found := cache.Get(ctx, "key1") + assert.True(t, found, "Expected to find the key") + assert.Equal(t, "value1", value, "Expected value to match") + + // Wait for the item to expire + time.Sleep(100 * time.Millisecond) + _, found = cache.Get(ctx, "key1") + assert.False(t, found, "Expected not to find the key after expiration") +} + +func TestMemoryCache_Delete(t *testing.T) { + cache := NewMemoryCache[string]() + defer cache.Stop() + + ctx := context.Background() + + // Set and delete a value + cache.Set(ctx, "key1", "value1", 0) + cache.Delete(ctx, "key1") + _, found := cache.Get(ctx, "key1") + assert.False(t, found, "Expected not to find the key after deletion") +} + +func TestMemoryCache_Clear(t *testing.T) { + cache := NewMemoryCache[string]() + defer cache.Stop() + + ctx := context.Background() + + // Set multiple values and clear the cache + cache.Set(ctx, "key1", "value1", 0) + cache.Set(ctx, "key2", "value2", 0) + cache.Clear(ctx) + assert.Equal(t, 0, cache.ItemCount(), "Expected cache to be empty after clearing") +} + +func TestMemoryCache_ItemCount(t *testing.T) { + cache := NewMemoryCache[string]() + defer cache.Stop() + + ctx := context.Background() + + // Test item count + assert.Equal(t, 0, cache.ItemCount(), "Expected item count to be 0 initially") + cache.Set(ctx, "key1", "value1", 0) + assert.Equal(t, 1, cache.ItemCount(), "Expected item count to be 1") + cache.Set(ctx, "key2", "value2", 0) + assert.Equal(t, 2, cache.ItemCount(), "Expected item count to be 2") + cache.Delete(ctx, "key1") + assert.Equal(t, 1, cache.ItemCount(), "Expected item count to be 1 after deletion") +} + +func TestMemoryCache_Options(t *testing.T) { + // Test WithCleanupInterval option + customInterval := 10 * time.Second + cache := NewMemoryCache(WithCleanupInterval[string](customInterval)) + defer cache.Stop() + + assert.Equal(t, customInterval, cache.cleanupInterval, "Expected custom cleanup interval") + + // Test WithName option + customName := "test-cache" + cache = NewMemoryCache(WithName[string](customName)) + defer cache.Stop() + + assert.Equal(t, customName, cache.name, "Expected custom cache name") + + // Test multiple options + cache = NewMemoryCache(WithCleanupInterval[string](customInterval), WithName[string](customName)) + defer cache.Stop() + + assert.Equal(t, customInterval, cache.cleanupInterval, "Expected custom cleanup interval") + assert.Equal(t, customName, cache.name, "Expected custom cache name") +} + +func TestMemoryCache_CleanupRoutine(t *testing.T) { + // Create cache with short cleanup interval + cache := NewMemoryCache(WithCleanupInterval[string](100 * time.Millisecond)) + defer cache.Stop() + + ctx := context.Background() + + // Add items with short expiration + cache.Set(ctx, "key1", "value1", 50*time.Millisecond) + cache.Set(ctx, "key2", "value2", 50*time.Millisecond) + cache.Set(ctx, "key3", "value3", 1*time.Hour) // This shouldn't expire + + // Wait for items to expire and cleanup to run + time.Sleep(200 * time.Millisecond) + + // Check that expired items were removed + _, found := cache.Get(ctx, "key1") + assert.False(t, found, "Expected key1 to be cleaned up") + + _, found = cache.Get(ctx, "key2") + assert.False(t, found, "Expected key2 to be cleaned up") + + // Check that non-expired item is still there + val, found := cache.Get(ctx, "key3") + assert.True(t, found, "Expected key3 to still exist") + assert.Equal(t, "value3", val) + + // Verify item count is correct + assert.Equal(t, 1, cache.ItemCount(), "Expected only one item remaining") +} + +func TestMemoryCache_Stop(t *testing.T) { + cache := NewMemoryCache[string]() + + // We can't easily test the stop functionality directly, + // but we can at least ensure it doesn't panic + cache.Stop() + + // Additional stop should panic (channel already closed) + require.Panics(t, func() { + cache.Stop() + }) +} + +func TestMemoryCache_DifferentTypes(t *testing.T) { + // Test with int type + intCache := NewMemoryCache[int]() + defer intCache.Stop() + + ctx := context.Background() + intCache.Set(ctx, "number", 42, 0) + val, found := intCache.Get(ctx, "number") + assert.True(t, found) + assert.Equal(t, 42, val) + + // Test with custom struct type + type Person struct { + Name string + Age int + } + + structCache := NewMemoryCache[Person]() + defer structCache.Stop() + + person := Person{Name: "John", Age: 30} + structCache.Set(ctx, "person", person, 0) + + retrievedPerson, found := structCache.Get(ctx, "person") + assert.True(t, found) + assert.Equal(t, person, retrievedPerson) +} diff --git a/pkg/cache/metrics.go b/pkg/cache/metrics.go new file mode 100644 index 00000000..575b635d --- /dev/null +++ b/pkg/cache/metrics.go @@ -0,0 +1,63 @@ +package cache + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +// Metric names and help text +const ( + cacheHitsName = "osctrl_cache_hits_total" + cacheHitsHelp = "Total number of cache hits" + cacheMissesName = "osctrl_cache_misses_total" + cacheMissesHelp = "Total number of cache misses" + cacheEvictionsName = "osctrl_cache_evictions_total" + cacheEvictionsHelp = "Total number of cache evictions" + cacheItemsName = "osctrl_cache_items" + cacheItemsHelp = "Current number of items in cache" +) + +var ( + // CacheHits tracks the number of cache hits + CacheHits = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: cacheHitsName, + Help: cacheHitsHelp, + }, + []string{"cache_name"}, + ) + + // CacheMisses tracks the number of cache misses + CacheMisses = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: cacheMissesName, + Help: cacheMissesHelp, + }, + []string{"cache_name"}, + ) + + // CacheEvictions tracks the number of cache evictions + CacheEvictions = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: cacheEvictionsName, + Help: cacheEvictionsHelp, + }, + []string{"cache_name"}, + ) + + // CacheItems tracks the current number of items in the cache + CacheItems = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: cacheItemsName, + Help: cacheItemsHelp, + }, + []string{"cache_name"}, + ) +) + +// RegisterMetrics registers all cache metrics with the provided registerer +func RegisterMetrics(reg prometheus.Registerer) { + reg.MustRegister(CacheHits) + reg.MustRegister(CacheMisses) + reg.MustRegister(CacheEvictions) + reg.MustRegister(CacheItems) +} diff --git a/pkg/environments/env-cache.go b/pkg/environments/env-cache.go new file mode 100644 index 00000000..1f66b843 --- /dev/null +++ b/pkg/environments/env-cache.go @@ -0,0 +1,75 @@ +package environments + +import ( + "context" + "time" + + "github.com/jmpsec/osctrl/pkg/cache" +) + +const ( + cacheName = "environments" +) + +// EnvCache provides cached access to TLS environments +type EnvCache struct { + // The cache itself, storing Environment objects + cache *cache.MemoryCache[TLSEnvironment] + + // Reference to the environment manager for cache misses + envs EnvManager +} + +// NewEnvCache creates a new environment cache +func NewEnvCache(envs EnvManager) *EnvCache { + // Create a new cache with a 10-minute cleanup interval + envCache := cache.NewMemoryCache( + cache.WithCleanupInterval[TLSEnvironment](2*time.Hour), + cache.WithName[TLSEnvironment](cacheName), + ) + + return &EnvCache{ + cache: envCache, + envs: envs, + } +} + +// GetByUUID retrieves an environment by UUID, using cache when available +func (ec *EnvCache) GetByUUID(ctx context.Context, uuid string) (TLSEnvironment, error) { + // Try to get from cache first + if env, found := ec.cache.Get(ctx, uuid); found { + return env, nil + } + + // Not in cache, fetch from database + env, err := ec.envs.GetByUUID(uuid) + if err != nil { + return TLSEnvironment{}, err + } + + ec.cache.Set(ctx, uuid, env, 2*time.Hour) + + return env, nil +} + +// InvalidateEnv removes a specific environment from the cache +func (ec *EnvCache) InvalidateEnv(ctx context.Context, uuid string) { + ec.cache.Delete(ctx, uuid) +} + +// InvalidateAll clears the entire cache +func (ec *EnvCache) InvalidateAll(ctx context.Context) { + ec.cache.Clear(ctx) +} + +// UpdateEnvInCache updates an environment in the cache +func (ec *EnvCache) UpdateEnvInCache(ctx context.Context, env TLSEnvironment) { + ec.cache.Set(ctx, env.UUID, env, 2*time.Hour) +} + +// Close stops the cleanup goroutine and releases resources +func (ec *EnvCache) Close() { + if ec.cache != nil { + ec.cache.Stop() + } +} diff --git a/pkg/environments/environments.go b/pkg/environments/environments.go index f4bc155c..26e6a720 100644 --- a/pkg/environments/environments.go +++ b/pkg/environments/environments.go @@ -109,14 +109,14 @@ type MapEnvByID map[uint]NameUUID // MapEnvByString to hold the environments name and UUID by string type MapEnvByString map[string]NameUUID -// Environment keeps all TLS Environments -type Environment struct { +// EnvManager keeps all TLS Environments +type EnvManager struct { DB *gorm.DB } // CreateEnvironment to initialize the environment struct and tables -func CreateEnvironment(backend *gorm.DB) *Environment { - var e *Environment = &Environment{DB: backend} +func CreateEnvironment(backend *gorm.DB) *EnvManager { + var e *EnvManager = &EnvManager{DB: backend} // table tls_environments if err := backend.AutoMigrate(&TLSEnvironment{}); err != nil { log.Fatal().Msgf("Failed to AutoMigrate table (tls_environments): %v", err) @@ -125,7 +125,7 @@ func CreateEnvironment(backend *gorm.DB) *Environment { } // Get TLS Environment by name or UUID -func (environment *Environment) Get(identifier string) (TLSEnvironment, error) { +func (environment *EnvManager) Get(identifier string) (TLSEnvironment, error) { var env TLSEnvironment if err := environment.DB.Where("name = ? OR uuid = ?", identifier, identifier).First(&env).Error; err != nil { return env, err @@ -134,7 +134,7 @@ func (environment *Environment) Get(identifier string) (TLSEnvironment, error) { } // Get TLS Environment by UUID -func (environment *Environment) GetByUUID(uuid string) (TLSEnvironment, error) { +func (environment *EnvManager) GetByUUID(uuid string) (TLSEnvironment, error) { var env TLSEnvironment if err := environment.DB.Where("uuid = ?", uuid).First(&env).Error; err != nil { return env, err @@ -143,7 +143,7 @@ func (environment *Environment) GetByUUID(uuid string) (TLSEnvironment, error) { } // Get TLS Environment by Name -func (environment *Environment) GetByName(name string) (TLSEnvironment, error) { +func (environment *EnvManager) GetByName(name string) (TLSEnvironment, error) { var env TLSEnvironment if err := environment.DB.Where("name = ?", name).First(&env).Error; err != nil { return env, err @@ -152,7 +152,7 @@ func (environment *Environment) GetByName(name string) (TLSEnvironment, error) { } // Get TLS Environment by ID -func (environment *Environment) GetByID(id uint) (TLSEnvironment, error) { +func (environment *EnvManager) GetByID(id uint) (TLSEnvironment, error) { var env TLSEnvironment if err := environment.DB.Where("ID = ?", id).First(&env).Error; err != nil { return env, err @@ -161,7 +161,7 @@ func (environment *Environment) GetByID(id uint) (TLSEnvironment, error) { } // Empty generates an empty TLSEnvironment with default values -func (environment *Environment) Empty(name, hostname string) TLSEnvironment { +func (environment *EnvManager) Empty(name, hostname string) TLSEnvironment { return TLSEnvironment{ UUID: utils.GenUUID(), Name: name, @@ -205,7 +205,7 @@ func (environment *Environment) Empty(name, hostname string) TLSEnvironment { } // Create new TLS Environment -func (environment *Environment) Create(env *TLSEnvironment) error { +func (environment *EnvManager) Create(env *TLSEnvironment) error { if err := environment.DB.Create(&env).Error; err != nil { return fmt.Errorf("Create TLS Environment %w", err) } @@ -213,14 +213,14 @@ func (environment *Environment) Create(env *TLSEnvironment) error { } // Exists checks if TLS Environment exists already -func (environment *Environment) Exists(identifier string) bool { +func (environment *EnvManager) Exists(identifier string) bool { var results int64 environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", identifier, identifier).Count(&results) return (results > 0) } // All gets all TLS Environment -func (environment *Environment) All() ([]TLSEnvironment, error) { +func (environment *EnvManager) All() ([]TLSEnvironment, error) { var envs []TLSEnvironment if err := environment.DB.Find(&envs).Error; err != nil { return envs, err @@ -229,7 +229,7 @@ func (environment *Environment) All() ([]TLSEnvironment, error) { } // Names gets just all TLS Environment names -func (environment *Environment) Names() ([]string, error) { +func (environment *EnvManager) Names() ([]string, error) { envs, err := environment.All() if err != nil { return []string{}, err @@ -242,7 +242,7 @@ func (environment *Environment) Names() ([]string, error) { } // UUIDs gets just all TLS Environment UUIDs -func (environment *Environment) UUIDs() ([]string, error) { +func (environment *EnvManager) UUIDs() ([]string, error) { envs, err := environment.All() if err != nil { return []string{}, err @@ -255,7 +255,7 @@ func (environment *Environment) UUIDs() ([]string, error) { } // GetMap returns the map of environments by name and UUID -func (environment *Environment) GetMap() (MapEnvironments, error) { +func (environment *EnvManager) GetMap() (MapEnvironments, error) { all, err := environment.All() if err != nil { return nil, fmt.Errorf("error getting environments %w", err) @@ -269,7 +269,7 @@ func (environment *Environment) GetMap() (MapEnvironments, error) { } // GetMapByID returns a smaller map of environments by ID -func (environment *Environment) GetMapByID() (MapEnvByID, error) { +func (environment *EnvManager) GetMapByID() (MapEnvByID, error) { all, err := environment.All() if err != nil { return nil, fmt.Errorf("error getting environments %w", err) @@ -287,7 +287,7 @@ func (environment *Environment) GetMapByID() (MapEnvByID, error) { } // GetMapByString returns a smaller map of environments by string (name and UUID) -func (environment *Environment) GetMapByString() (MapEnvByString, error) { +func (environment *EnvManager) GetMapByString() (MapEnvByString, error) { all, err := environment.All() if err != nil { return nil, fmt.Errorf("error getting environments %w", err) @@ -306,7 +306,7 @@ func (environment *Environment) GetMapByString() (MapEnvByString, error) { } // Delete TLS Environment by name or UUID -func (environment *Environment) Delete(identifier string) error { +func (environment *EnvManager) Delete(identifier string) error { env, err := environment.Get(identifier) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -318,7 +318,7 @@ func (environment *Environment) Delete(identifier string) error { } // Update TLS Environment -func (environment *Environment) Update(e TLSEnvironment) error { +func (environment *EnvManager) Update(e TLSEnvironment) error { env, err := environment.Get(e.Name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -330,7 +330,7 @@ func (environment *Environment) Update(e TLSEnvironment) error { } // UpdateOptions to update options for an environment -func (environment *Environment) UpdateOptions(idEnv, options string) error { +func (environment *EnvManager) UpdateOptions(idEnv, options string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("options", options).Error; err != nil { return fmt.Errorf("Update options %w", err) } @@ -338,7 +338,7 @@ func (environment *Environment) UpdateOptions(idEnv, options string) error { } // UpdateSchedule to update schedule for an environment -func (environment *Environment) UpdateSchedule(idEnv, schedule string) error { +func (environment *EnvManager) UpdateSchedule(idEnv, schedule string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("schedule", schedule).Error; err != nil { return fmt.Errorf("Update schedule %w", err) } @@ -346,7 +346,7 @@ func (environment *Environment) UpdateSchedule(idEnv, schedule string) error { } // UpdatePacks to update packs for an environment -func (environment *Environment) UpdatePacks(idEnv, packs string) error { +func (environment *EnvManager) UpdatePacks(idEnv, packs string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("packs", packs).Error; err != nil { return fmt.Errorf("Update packs %w", err) } @@ -354,7 +354,7 @@ func (environment *Environment) UpdatePacks(idEnv, packs string) error { } // UpdateDecorators to update decorators for an environment -func (environment *Environment) UpdateDecorators(idEnv, decorators string) error { +func (environment *EnvManager) UpdateDecorators(idEnv, decorators string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("decorators", decorators).Error; err != nil { return fmt.Errorf("Update decorators %w", err) } @@ -362,7 +362,7 @@ func (environment *Environment) UpdateDecorators(idEnv, decorators string) error } // UpdateATC to update ATC for an environment -func (environment *Environment) UpdateATC(idEnv, atc string) error { +func (environment *EnvManager) UpdateATC(idEnv, atc string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("atc", atc).Error; err != nil { return fmt.Errorf("Update ATC %w", err) } @@ -370,7 +370,7 @@ func (environment *Environment) UpdateATC(idEnv, atc string) error { } // UpdateCertificate to update decorators for an environment -func (environment *Environment) UpdateCertificate(idEnv, certificate string) error { +func (environment *EnvManager) UpdateCertificate(idEnv, certificate string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("certificate", certificate).Error; err != nil { return fmt.Errorf("UpdateUpdateCertificate %w", err) } @@ -378,7 +378,7 @@ func (environment *Environment) UpdateCertificate(idEnv, certificate string) err } // UpdateDebPackage to update DEB package for an environment -func (environment *Environment) UpdateDebPackage(idEnv, debpackage string) error { +func (environment *EnvManager) UpdateDebPackage(idEnv, debpackage string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("deb_package", debpackage).Error; err != nil { return fmt.Errorf("UpdateDebPackage %w", err) } @@ -386,7 +386,7 @@ func (environment *Environment) UpdateDebPackage(idEnv, debpackage string) error } // UpdateRpmPackage to update RPM package for an environment -func (environment *Environment) UpdateRpmPackage(idEnv, rpmpackage string) error { +func (environment *EnvManager) UpdateRpmPackage(idEnv, rpmpackage string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("rpm_package", rpmpackage).Error; err != nil { return fmt.Errorf("UpdateRpmPackage %w", err) } @@ -394,7 +394,7 @@ func (environment *Environment) UpdateRpmPackage(idEnv, rpmpackage string) error } // UpdateMsiPackage to update MSI package for an environment -func (environment *Environment) UpdateMsiPackage(idEnv, msipackage string) error { +func (environment *EnvManager) UpdateMsiPackage(idEnv, msipackage string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("msi_package", msipackage).Error; err != nil { return fmt.Errorf("UpdateMsiPackage %w", err) } @@ -402,7 +402,7 @@ func (environment *Environment) UpdateMsiPackage(idEnv, msipackage string) error } // UpdatePkgPackage to update PKG package for an environment -func (environment *Environment) UpdatePkgPackage(idEnv, pkgpackage string) error { +func (environment *EnvManager) UpdatePkgPackage(idEnv, pkgpackage string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("pkg_package", pkgpackage).Error; err != nil { return fmt.Errorf("UpdatePkgPackage %w", err) } @@ -410,7 +410,7 @@ func (environment *Environment) UpdatePkgPackage(idEnv, pkgpackage string) error } // UpdateFlags to update flags for an environment -func (environment *Environment) UpdateFlags(idEnv, flags string) error { +func (environment *EnvManager) UpdateFlags(idEnv, flags string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("flags", flags).Error; err != nil { return fmt.Errorf("Update flags %w", err) } @@ -418,7 +418,7 @@ func (environment *Environment) UpdateFlags(idEnv, flags string) error { } // UpdateHostname to update hostname for an environment -func (environment *Environment) UpdateHostname(idEnv, hostname string) error { +func (environment *EnvManager) UpdateHostname(idEnv, hostname string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("hostname", hostname).Error; err != nil { return fmt.Errorf("Update hostname %w", err) } @@ -426,7 +426,7 @@ func (environment *Environment) UpdateHostname(idEnv, hostname string) error { } // UpdateIntervals to update intervals for an environment -func (environment *Environment) UpdateIntervals(name string, csecs, lsecs, qsecs int) error { +func (environment *EnvManager) UpdateIntervals(name string, csecs, lsecs, qsecs int) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -442,7 +442,7 @@ func (environment *Environment) UpdateIntervals(name string, csecs, lsecs, qsecs } // RotateSecrets to replace Secret and SecretPath for an environment -func (environment *Environment) RotateSecrets(name string) error { +func (environment *EnvManager) RotateSecrets(name string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -460,7 +460,7 @@ func (environment *Environment) RotateSecrets(name string) error { } // RotateEnrollPath to replace SecretPath for enrolling in an environment -func (environment *Environment) RotateEnroll(name string) error { +func (environment *EnvManager) RotateEnroll(name string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -475,7 +475,7 @@ func (environment *Environment) RotateEnroll(name string) error { } // RotateSecret to replace the current Secret for an environment -func (environment *Environment) RotateSecret(name string) error { +func (environment *EnvManager) RotateSecret(name string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -490,7 +490,7 @@ func (environment *Environment) RotateSecret(name string) error { } // ExpireEnroll to expire the enroll in an environment -func (environment *Environment) ExpireEnroll(idEnv string) error { +func (environment *EnvManager) ExpireEnroll(idEnv string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("enroll_expire", time.Now()).Error; err != nil { return fmt.Errorf("UpdateExpireEnroll %w", err) } @@ -498,7 +498,7 @@ func (environment *Environment) ExpireEnroll(idEnv string) error { } // ExtendEnroll to extend the enroll in an environment -func (environment *Environment) ExtendEnroll(idEnv string) error { +func (environment *EnvManager) ExtendEnroll(idEnv string) error { extended := time.Now().Add(time.Duration(DefaultLinkExpire) * time.Hour) if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("enroll_expire", extended).Error; err != nil { return fmt.Errorf("UpdateExtendEnroll %w", err) @@ -507,7 +507,7 @@ func (environment *Environment) ExtendEnroll(idEnv string) error { } // NotExpireEnroll to mark the enroll in an environment as not expiring -func (environment *Environment) NotExpireEnroll(idEnv string) error { +func (environment *EnvManager) NotExpireEnroll(idEnv string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("enroll_expire", time.Time{}).Error; err != nil { return fmt.Errorf("NotExpireEnroll %w", err) } @@ -515,7 +515,7 @@ func (environment *Environment) NotExpireEnroll(idEnv string) error { } // RotateRemove to replace Secret and SecretPath for enrolling in an environment -func (environment *Environment) RotateRemove(name string) error { +func (environment *EnvManager) RotateRemove(name string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -530,7 +530,7 @@ func (environment *Environment) RotateRemove(name string) error { } // ExpireRemove to expire the remove in an environment -func (environment *Environment) ExpireRemove(idEnv string) error { +func (environment *EnvManager) ExpireRemove(idEnv string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("remove_expire", time.Now()).Error; err != nil { return fmt.Errorf("UpdateExpireRemove %w", err) } @@ -538,7 +538,7 @@ func (environment *Environment) ExpireRemove(idEnv string) error { } // ExtendRemove to extend the remove in an environment -func (environment *Environment) ExtendRemove(idEnv string) error { +func (environment *EnvManager) ExtendRemove(idEnv string) error { env, err := environment.Get(idEnv) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -551,7 +551,7 @@ func (environment *Environment) ExtendRemove(idEnv string) error { } // NotExpireRemove to mark the remove in an environment as not expiring -func (environment *Environment) NotExpireRemove(idEnv string) error { +func (environment *EnvManager) NotExpireRemove(idEnv string) error { if err := environment.DB.Model(&TLSEnvironment{}).Where("name = ? OR uuid = ?", idEnv, idEnv).Update("remove_expire", time.Time{}).Error; err != nil { return fmt.Errorf("NotExpireRemove %w", err) } diff --git a/pkg/environments/flags.go b/pkg/environments/flags.go index 198908a0..f4bd56e4 100644 --- a/pkg/environments/flags.go +++ b/pkg/environments/flags.go @@ -102,7 +102,7 @@ func ParseFlagTemplate(tmplName, flagTemplate string, data interface{}) string { } // GenerateFlags to generate flags -func (environment *Environment) GenerateFlags(env TLSEnvironment, secretPath, certPath string) (string, error) { +func (environment *EnvManager) GenerateFlags(env TLSEnvironment, secretPath, certPath string) (string, error) { flagSecret := secretPath if secretPath == "" { flagSecret = EmptyFlagSecret @@ -125,7 +125,7 @@ func (environment *Environment) GenerateFlags(env TLSEnvironment, secretPath, ce } // GenerateFlagsEnv to generate flags by environment name -func (environment *Environment) GenerateFlagsEnv(idEnv string, secretPath, certPath string) (string, error) { +func (environment *EnvManager) GenerateFlagsEnv(idEnv string, secretPath, certPath string) (string, error) { env, err := environment.Get(idEnv) if err != nil { return "", fmt.Errorf("error getting environment %w", err) diff --git a/pkg/environments/osqueryconf.go b/pkg/environments/osqueryconf.go index c93ff5a0..40fbe9c2 100644 --- a/pkg/environments/osqueryconf.go +++ b/pkg/environments/osqueryconf.go @@ -65,7 +65,7 @@ type DecoratorConf struct { type ATCConf map[string]interface{} // RefreshConfiguration to take all parts and put them together in the configuration -func (environment *Environment) RefreshConfiguration(idEnv string) error { +func (environment *EnvManager) RefreshConfiguration(idEnv string) error { env, err := environment.Get(idEnv) if err != nil { return fmt.Errorf("error structuring environment %w", err) @@ -108,7 +108,7 @@ func (environment *Environment) RefreshConfiguration(idEnv string) error { } // UpdateConfiguration to update configuration for an environment -func (environment *Environment) UpdateConfiguration(idEnv string, cnf OsqueryConf) error { +func (environment *EnvManager) UpdateConfiguration(idEnv string, cnf OsqueryConf) error { indentedConf, err := environment.GenSerializedConf(cnf, true) if err != nil { return fmt.Errorf("error serializing configuration %w", err) @@ -120,7 +120,7 @@ func (environment *Environment) UpdateConfiguration(idEnv string, cnf OsqueryCon } // UpdateConfigurationParts to update all the configuration parts for an environment -func (environment *Environment) UpdateConfigurationParts(idEnv string, cnf OsqueryConf) error { +func (environment *EnvManager) UpdateConfigurationParts(idEnv string, cnf OsqueryConf) error { indentedOptions, err := environment.GenSerializedConf(cnf.Options, true) if err != nil { return fmt.Errorf("error serializing options %w", err) @@ -153,7 +153,7 @@ func (environment *Environment) UpdateConfigurationParts(idEnv string, cnf Osque } // GenSerializedConf to generate a serialized osquery configuration from the structured data -func (environment *Environment) GenSerializedConf(structured interface{}, indent bool) (string, error) { +func (environment *EnvManager) GenSerializedConf(structured interface{}, indent bool) (string, error) { indentStr := "" if indent { indentStr = " " @@ -166,7 +166,7 @@ func (environment *Environment) GenSerializedConf(structured interface{}, indent } // GenStructConf to generate the components from the osquery configuration -func (environment *Environment) GenStructConf(configuration []byte) (OsqueryConf, error) { +func (environment *EnvManager) GenStructConf(configuration []byte) (OsqueryConf, error) { var data OsqueryConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -175,7 +175,7 @@ func (environment *Environment) GenStructConf(configuration []byte) (OsqueryConf } // GenStructOptions to generate options from the serialized string -func (environment *Environment) GenStructOptions(configuration []byte) (OptionsConf, error) { +func (environment *EnvManager) GenStructOptions(configuration []byte) (OptionsConf, error) { var data OptionsConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -184,7 +184,7 @@ func (environment *Environment) GenStructOptions(configuration []byte) (OptionsC } // GenStructSchedule to generate schedule from the serialized string -func (environment *Environment) GenStructSchedule(configuration []byte) (ScheduleConf, error) { +func (environment *EnvManager) GenStructSchedule(configuration []byte) (ScheduleConf, error) { var data ScheduleConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -193,7 +193,7 @@ func (environment *Environment) GenStructSchedule(configuration []byte) (Schedul } // NodeStructSchedule to generate schedule that applies to a platform from the serialized string -func (environment *Environment) NodeStructSchedule(configuration []byte, platform string) (ScheduleConf, error) { +func (environment *EnvManager) NodeStructSchedule(configuration []byte, platform string) (ScheduleConf, error) { schedule, err := environment.GenStructSchedule(configuration) if err != nil { return ScheduleConf{}, fmt.Errorf("GenStructSchedule %w", err) @@ -207,7 +207,7 @@ func (environment *Environment) NodeStructSchedule(configuration []byte, platfor } // GenStructPacks to generate packs from the serialized string -func (environment *Environment) GenStructPacks(configuration []byte) (PacksConf, error) { +func (environment *EnvManager) GenStructPacks(configuration []byte) (PacksConf, error) { var data PacksConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -216,7 +216,7 @@ func (environment *Environment) GenStructPacks(configuration []byte) (PacksConf, } // NodePacksEntries to generate packs parsed struct that applies to a platform from the serialized string -func (environment *Environment) NodePacksEntries(configuration []byte, platform string) (PacksEntries, error) { +func (environment *EnvManager) NodePacksEntries(configuration []byte, platform string) (PacksEntries, error) { packs, err := environment.GenPacksEntries(configuration) if err != nil { return PacksEntries{}, fmt.Errorf("GenPacksEntries %w", err) @@ -230,7 +230,7 @@ func (environment *Environment) NodePacksEntries(configuration []byte, platform } // GenPacksEntries to generate packs parsed struct from the serialized string -func (environment *Environment) GenPacksEntries(configuration []byte) (PacksEntries, error) { +func (environment *EnvManager) GenPacksEntries(configuration []byte) (PacksEntries, error) { packsConf, err := environment.GenStructPacks(configuration) if err != nil { return PacksEntries{}, fmt.Errorf("GenStructPacks %w", err) @@ -256,7 +256,7 @@ func (environment *Environment) GenPacksEntries(configuration []byte) (PacksEntr } // GenStructDecorators to generate decorators from the serialized string -func (environment *Environment) GenStructDecorators(configuration []byte) (DecoratorConf, error) { +func (environment *EnvManager) GenStructDecorators(configuration []byte) (DecoratorConf, error) { var data DecoratorConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -265,7 +265,7 @@ func (environment *Environment) GenStructDecorators(configuration []byte) (Decor } // GenStructATC to generate ATC from the serialized string -func (environment *Environment) GenStructATC(configuration []byte) (ATCConf, error) { +func (environment *EnvManager) GenStructATC(configuration []byte) (ATCConf, error) { var data ATCConf if err := json.Unmarshal(configuration, &data); err != nil { return data, err @@ -274,7 +274,7 @@ func (environment *Environment) GenStructATC(configuration []byte) (ATCConf, err } // GenEmptyConfiguration to generate a serialized string with an empty configuration -func (environment *Environment) GenEmptyConfiguration(indent bool) string { +func (environment *EnvManager) GenEmptyConfiguration(indent bool) string { cnf := OsqueryConf{ Options: OptionsConf{}, Schedule: ScheduleConf{}, @@ -298,7 +298,7 @@ func (environment *Environment) GenEmptyConfiguration(indent bool) string { } // AddOptionsConf to add an osquery option to the configuration -func (environment *Environment) AddOptionsConf(name, option string, value interface{}) error { +func (environment *EnvManager) AddOptionsConf(name, option string, value interface{}) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -327,7 +327,7 @@ func (environment *Environment) AddOptionsConf(name, option string, value interf } // RemoveOptionsConf to remove an osquery option from the configuration -func (environment *Environment) RemoveOptionsConf(name, option string) error { +func (environment *EnvManager) RemoveOptionsConf(name, option string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -356,7 +356,7 @@ func (environment *Environment) RemoveOptionsConf(name, option string) error { } // AddScheduleConfQuery to add a new query to the osquery schedule -func (environment *Environment) AddScheduleConfQuery(name, qName string, query ScheduleQuery) error { +func (environment *EnvManager) AddScheduleConfQuery(name, qName string, query ScheduleQuery) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -385,7 +385,7 @@ func (environment *Environment) AddScheduleConfQuery(name, qName string, query S } // RemoveScheduleConfQuery to remove a query from the osquery schedule -func (environment *Environment) RemoveScheduleConfQuery(name, qName string) error { +func (environment *EnvManager) RemoveScheduleConfQuery(name, qName string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -414,7 +414,7 @@ func (environment *Environment) RemoveScheduleConfQuery(name, qName string) erro } // AddQueryPackConf to add a new query pack to the osquery configuration -func (environment *Environment) AddQueryPackConf(name, pName string, pack interface{}) error { +func (environment *EnvManager) AddQueryPackConf(name, pName string, pack interface{}) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -443,7 +443,7 @@ func (environment *Environment) AddQueryPackConf(name, pName string, pack interf } // RemoveQueryPackConf to add a new query pack to the osquery configuration -func (environment *Environment) RemoveQueryPackConf(name, pName string) error { +func (environment *EnvManager) RemoveQueryPackConf(name, pName string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -472,7 +472,7 @@ func (environment *Environment) RemoveQueryPackConf(name, pName string) error { } // AddQueryToPackConf to add a new query to an existing pack in the osquery configuration -func (environment *Environment) AddQueryToPackConf(name, pName, qName string, query ScheduleQuery) error { +func (environment *EnvManager) AddQueryToPackConf(name, pName, qName string, query ScheduleQuery) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err) @@ -503,7 +503,7 @@ func (environment *Environment) AddQueryToPackConf(name, pName, qName string, qu } // RemoveQueryFromPackConf to remove a query from an existing query pack in the osquery configuration -func (environment *Environment) RemoveQueryFromPackConf(name, pName, qName string) error { +func (environment *EnvManager) RemoveQueryFromPackConf(name, pName, qName string) error { env, err := environment.Get(name) if err != nil { return fmt.Errorf("error getting environment %w", err)