database.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package database
  2. import (
  3. "errors"
  4. "sync"
  5. "time"
  6. "github.com/gravitl/netmaker/logger"
  7. "github.com/gravitl/netmaker/servercfg"
  8. )
  9. const (
  10. // == Table Names ==
  11. // NETWORKS_TABLE_NAME - networks table
  12. NETWORKS_TABLE_NAME = "networks"
  13. // NODES_TABLE_NAME - nodes table
  14. NODES_TABLE_NAME = "nodes"
  15. // DELETED_NODES_TABLE_NAME - deleted nodes table
  16. DELETED_NODES_TABLE_NAME = "deletednodes"
  17. // USERS_TABLE_NAME - users table
  18. USERS_TABLE_NAME = "users"
  19. // ACCESS_TOKENS_TABLE_NAME - access tokens table
  20. ACCESS_TOKENS_TABLE_NAME = "user_access_tokens"
  21. // USER_PERMISSIONS_TABLE_NAME - user permissions table
  22. USER_PERMISSIONS_TABLE_NAME = "user_permissions"
  23. // CERTS_TABLE_NAME - certificates table
  24. CERTS_TABLE_NAME = "certs"
  25. // DNS_TABLE_NAME - dns table
  26. DNS_TABLE_NAME = "dns"
  27. // EXT_CLIENT_TABLE_NAME - ext client table
  28. EXT_CLIENT_TABLE_NAME = "extclients"
  29. // PEERS_TABLE_NAME - peers table
  30. PEERS_TABLE_NAME = "peers"
  31. // SERVERCONF_TABLE_NAME - stores server conf
  32. SERVERCONF_TABLE_NAME = "serverconf"
  33. // SERVER_UUID_TABLE_NAME - stores unique netmaker server data
  34. SERVER_UUID_TABLE_NAME = "serveruuid"
  35. // SERVER_UUID_RECORD_KEY - telemetry thing
  36. SERVER_UUID_RECORD_KEY = "serveruuid"
  37. // DATABASE_FILENAME - database file name
  38. DATABASE_FILENAME = "netmaker.db"
  39. // GENERATED_TABLE_NAME - stores server generated k/v
  40. GENERATED_TABLE_NAME = "generated"
  41. // NODE_ACLS_TABLE_NAME - stores the node ACL rules
  42. NODE_ACLS_TABLE_NAME = "nodeacls"
  43. // ACLS_TABLE_NAME - table for acls v2
  44. ACLS_TABLE_NAME = "acls"
  45. // SSO_STATE_CACHE - holds sso session information for OAuth2 sign-ins
  46. SSO_STATE_CACHE = "ssostatecache"
  47. // METRICS_TABLE_NAME - stores network metrics
  48. METRICS_TABLE_NAME = "metrics"
  49. // NETWORK_USER_TABLE_NAME - network user table tracks stats for a network user per network
  50. NETWORK_USER_TABLE_NAME = "networkusers"
  51. // USER_GROUPS_TABLE_NAME - table for storing usergroups
  52. USER_GROUPS_TABLE_NAME = "usergroups"
  53. // CACHE_TABLE_NAME - caching table
  54. CACHE_TABLE_NAME = "cache"
  55. // HOSTS_TABLE_NAME - the table name for hosts
  56. HOSTS_TABLE_NAME = "hosts"
  57. // ENROLLMENT_KEYS_TABLE_NAME - table name for enrollmentkeys
  58. ENROLLMENT_KEYS_TABLE_NAME = "enrollmentkeys"
  59. // HOST_ACTIONS_TABLE_NAME - table name for enrollmentkeys
  60. HOST_ACTIONS_TABLE_NAME = "hostactions"
  61. // PENDING_USERS_TABLE_NAME - table name for pending users
  62. PENDING_USERS_TABLE_NAME = "pending_users"
  63. // USER_INVITES - table for user invites
  64. USER_INVITES_TABLE_NAME = "user_invites"
  65. // TAG_TABLE_NAME - table for tags
  66. TAG_TABLE_NAME = "tags"
  67. // PEER_ACK_TABLE - table for failover peer ack
  68. PEER_ACK_TABLE = "peer_ack"
  69. // SERVER_SETTINGS - table for server settings
  70. SERVER_SETTINGS = "server_settings"
  71. // == ERROR CONSTS ==
  72. // NO_RECORD - no singular result found
  73. NO_RECORD = "no result found"
  74. // NO_RECORDS - no results found
  75. NO_RECORDS = "could not find any records"
  76. // == DB Constants ==
  77. // INIT_DB - initialize db
  78. INIT_DB = "init"
  79. // CREATE_TABLE - create table const
  80. CREATE_TABLE = "createtable"
  81. // INSERT - insert into db const
  82. INSERT = "insert"
  83. // INSERT_PEER - insert peer into db const
  84. INSERT_PEER = "insertpeer"
  85. // DELETE - delete db record const
  86. DELETE = "delete"
  87. // DELETE_ALL - delete a table const
  88. DELETE_ALL = "deleteall"
  89. // FETCH_ALL - fetch table contents const
  90. FETCH_ALL = "fetchall"
  91. // CLOSE_DB - graceful close of db const
  92. CLOSE_DB = "closedb"
  93. // isconnected
  94. isConnected = "isconnected"
  95. )
  96. var dbMutex sync.RWMutex
  97. var Tables = []string{
  98. NETWORKS_TABLE_NAME,
  99. NODES_TABLE_NAME,
  100. CERTS_TABLE_NAME,
  101. DELETED_NODES_TABLE_NAME,
  102. USERS_TABLE_NAME,
  103. DNS_TABLE_NAME,
  104. EXT_CLIENT_TABLE_NAME,
  105. PEERS_TABLE_NAME,
  106. SERVERCONF_TABLE_NAME,
  107. SERVER_UUID_TABLE_NAME,
  108. GENERATED_TABLE_NAME,
  109. NODE_ACLS_TABLE_NAME,
  110. SSO_STATE_CACHE,
  111. METRICS_TABLE_NAME,
  112. NETWORK_USER_TABLE_NAME,
  113. USER_GROUPS_TABLE_NAME,
  114. CACHE_TABLE_NAME,
  115. HOSTS_TABLE_NAME,
  116. ENROLLMENT_KEYS_TABLE_NAME,
  117. HOST_ACTIONS_TABLE_NAME,
  118. PENDING_USERS_TABLE_NAME,
  119. USER_PERMISSIONS_TABLE_NAME,
  120. USER_INVITES_TABLE_NAME,
  121. TAG_TABLE_NAME,
  122. ACLS_TABLE_NAME,
  123. PEER_ACK_TABLE,
  124. SERVER_SETTINGS,
  125. }
  126. func getCurrentDB() map[string]interface{} {
  127. switch servercfg.GetDB() {
  128. case "rqlite":
  129. return RQLITE_FUNCTIONS
  130. case "sqlite":
  131. return SQLITE_FUNCTIONS
  132. case "postgres":
  133. return PG_FUNCTIONS
  134. default:
  135. return SQLITE_FUNCTIONS
  136. }
  137. }
  138. // InitializeDatabase - initializes database
  139. func InitializeDatabase() error {
  140. logger.Log(0, "connecting to", servercfg.GetDB())
  141. tperiod := time.Now().Add(10 * time.Second)
  142. for {
  143. if err := getCurrentDB()[INIT_DB].(func() error)(); err != nil {
  144. logger.Log(0, "unable to connect to db, retrying . . .")
  145. if time.Now().After(tperiod) {
  146. return err
  147. }
  148. } else {
  149. break
  150. }
  151. time.Sleep(2 * time.Second)
  152. }
  153. createTables()
  154. return nil
  155. }
  156. func createTables() {
  157. for _, table := range Tables {
  158. _ = CreateTable(table)
  159. }
  160. }
  161. func CreateTable(tableName string) error {
  162. return getCurrentDB()[CREATE_TABLE].(func(string) error)(tableName)
  163. }
  164. // Insert - inserts object into db
  165. func Insert(key string, value string, tableName string) error {
  166. dbMutex.Lock()
  167. defer dbMutex.Unlock()
  168. if key != "" && value != "" {
  169. return getCurrentDB()[INSERT].(func(string, string, string) error)(key, value, tableName)
  170. } else {
  171. return errors.New("invalid insert " + key + " : " + value)
  172. }
  173. }
  174. // DeleteRecord - deletes a record from db
  175. func DeleteRecord(tableName string, key string) error {
  176. dbMutex.Lock()
  177. defer dbMutex.Unlock()
  178. return getCurrentDB()[DELETE].(func(string, string) error)(tableName, key)
  179. }
  180. // DeleteAllRecords - removes a table and remakes
  181. func DeleteAllRecords(tableName string) error {
  182. dbMutex.Lock()
  183. defer dbMutex.Unlock()
  184. err := getCurrentDB()[DELETE_ALL].(func(string) error)(tableName)
  185. if err != nil {
  186. return err
  187. }
  188. err = CreateTable(tableName)
  189. if err != nil {
  190. return err
  191. }
  192. return nil
  193. }
  194. // FetchRecord - fetches a record
  195. func FetchRecord(tableName string, key string) (string, error) {
  196. results, err := FetchRecords(tableName)
  197. if err != nil {
  198. return "", err
  199. }
  200. if results[key] == "" {
  201. return "", errors.New(NO_RECORD)
  202. }
  203. return results[key], nil
  204. }
  205. // FetchRecords - fetches all records in given table
  206. func FetchRecords(tableName string) (map[string]string, error) {
  207. dbMutex.RLock()
  208. defer dbMutex.RUnlock()
  209. return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName)
  210. }
  211. // CloseDB - closes a database gracefully
  212. func CloseDB() {
  213. getCurrentDB()[CLOSE_DB].(func())()
  214. }
  215. // IsConnected - tell if the database is connected or not
  216. func IsConnected() bool {
  217. return getCurrentDB()[isConnected].(func() bool)()
  218. }