olivetin/service/internal/entities/storage.go

113 lines
2.4 KiB
Go

package entities
/**
* The ephemeralvariablemap is used "only" for variable substitution in config
* titles, shell arguments, etc, in the foorm of {{ key }}, like Jinja2.
*
* OliveTin itself really only ever "writes" to this map, mostly by loading
* EntityFiles, and the only form of "reading" is for the variable substitution
* in configs.
*/
import (
"strings"
"sync"
)
type entityInstancesByKey map[string]*Entity
type EntitiesByClass map[string]entityInstancesByKey
var (
rwmutex = sync.RWMutex{}
entities EntitiesByClass
)
func init() {
rwmutex.Lock()
entities = make(EntitiesByClass, 0)
rwmutex.Unlock()
}
func GetEntities() EntitiesByClass {
rwmutex.RLock()
copiedEntities := make(EntitiesByClass, len(entities))
for entityName, entityInstances := range entities {
copiedInstances := make(entityInstancesByKey, len(entityInstances))
for key, entity := range entityInstances {
copiedInstances[key] = entity
}
copiedEntities[entityName] = copiedInstances
}
rwmutex.RUnlock()
return copiedEntities
}
func GetEntityInstances(entityName string) entityInstancesByKey {
rwmutex.RLock()
defer rwmutex.RUnlock()
if entities, ok := entities[entityName]; ok {
copiedInstances := make(entityInstancesByKey, len(entities))
for key, entity := range entities {
copiedInstances[key] = entity
}
return copiedInstances
}
return make(entityInstancesByKey, 0)
}
func AddEntity(entityName string, entityKey string, data any) {
rwmutex.Lock()
if _, ok := entities[entityName]; !ok {
entities[entityName] = make(entityInstancesByKey, 0)
}
entities[entityName][entityKey] = &Entity{
Data: data,
UniqueKey: entityKey,
Title: findEntityTitle(data),
}
rwmutex.Unlock()
}
//gocyclo:ignore
func findEntityTitle(data any) string {
if mapData, ok := data.(map[string]any); ok {
keys := make(map[string]string)
for k := range mapData {
lookupKey := strings.ToLower(k)
keys[lookupKey] = k
}
for _, key := range []string{"title", "name", "id", "hostname", "host", "label"} {
if lookupKey, exists := keys[strings.ToLower(key)]; exists {
if value, ok := mapData[lookupKey]; ok {
if valueStr, ok := value.(string); ok {
return valueStr
}
}
}
}
}
return "Untitled Entity"
}
func ClearEntitiesOfType(entityType string) {
rwmutex.Lock()
defer rwmutex.Unlock()
delete(entities, entityType)
}