storage.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package entities
  2. /**
  3. * The ephemeralvariablemap is used "only" for variable substitution in config
  4. * titles, shell arguments, etc, in the foorm of {{ key }}, like Jinja2.
  5. *
  6. * OliveTin itself really only ever "writes" to this map, mostly by loading
  7. * EntityFiles, and the only form of "reading" is for the variable substitution
  8. * in configs.
  9. */
  10. import (
  11. "strings"
  12. "sync"
  13. )
  14. type entityInstancesByKey map[string]*Entity
  15. type EntitiesByClass map[string]entityInstancesByKey
  16. var (
  17. rwmutex = sync.RWMutex{}
  18. entities EntitiesByClass
  19. )
  20. func init() {
  21. rwmutex.Lock()
  22. entities = make(EntitiesByClass, 0)
  23. rwmutex.Unlock()
  24. }
  25. func GetEntities() EntitiesByClass {
  26. rwmutex.RLock()
  27. copiedEntities := make(EntitiesByClass, len(entities))
  28. for entityName, entityInstances := range entities {
  29. copiedInstances := make(entityInstancesByKey, len(entityInstances))
  30. for key, entity := range entityInstances {
  31. copiedInstances[key] = entity
  32. }
  33. copiedEntities[entityName] = copiedInstances
  34. }
  35. rwmutex.RUnlock()
  36. return copiedEntities
  37. }
  38. func GetEntityInstances(entityName string) entityInstancesByKey {
  39. rwmutex.RLock()
  40. defer rwmutex.RUnlock()
  41. if entities, ok := entities[entityName]; ok {
  42. copiedInstances := make(entityInstancesByKey, len(entities))
  43. for key, entity := range entities {
  44. copiedInstances[key] = entity
  45. }
  46. return copiedInstances
  47. }
  48. return make(entityInstancesByKey, 0)
  49. }
  50. func AddEntity(entityName string, entityKey string, data any) {
  51. rwmutex.Lock()
  52. if _, ok := entities[entityName]; !ok {
  53. entities[entityName] = make(entityInstancesByKey, 0)
  54. }
  55. entities[entityName][entityKey] = &Entity{
  56. Data: data,
  57. UniqueKey: entityKey,
  58. Title: findEntityTitle(data),
  59. }
  60. rwmutex.Unlock()
  61. }
  62. //gocyclo:ignore
  63. func findEntityTitle(data any) string {
  64. if mapData, ok := data.(map[string]any); ok {
  65. keys := make(map[string]string)
  66. for k := range mapData {
  67. lookupKey := strings.ToLower(k)
  68. keys[lookupKey] = k
  69. }
  70. for _, key := range []string{"title", "name", "id", "hostname", "host", "label"} {
  71. if lookupKey, exists := keys[strings.ToLower(key)]; exists {
  72. if value, ok := mapData[lookupKey]; ok {
  73. if valueStr, ok := value.(string); ok {
  74. return valueStr
  75. }
  76. }
  77. }
  78. }
  79. }
  80. return "Untitled Entity"
  81. }
  82. func ClearEntitiesOfType(entityType string) {
  83. rwmutex.Lock()
  84. defer rwmutex.Unlock()
  85. delete(entities, entityType)
  86. }