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) }