2
0

database.go 6.4 KB

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