helpers.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. package functions
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "math/rand"
  7. "strings"
  8. "time"
  9. "github.com/gravitl/netmaker/database"
  10. "github.com/gravitl/netmaker/logic"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/servercfg"
  13. )
  14. // PrintUserLog - prints a log with a given username
  15. func PrintUserLog(username string, message string, loglevel int) {
  16. log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
  17. if int32(loglevel) <= servercfg.GetVerbose() && servercfg.GetVerbose() != 0 {
  18. log.Println("[netmaker]", username, message)
  19. }
  20. }
  21. // ParseNetwork - parses a network into a model
  22. func ParseNetwork(value string) (models.Network, error) {
  23. var network models.Network
  24. err := json.Unmarshal([]byte(value), &network)
  25. return network, err
  26. }
  27. // ParseNode - parses a node into a model
  28. func ParseNode(value string) (models.Node, error) {
  29. var node models.Node
  30. err := json.Unmarshal([]byte(value), &node)
  31. return node, err
  32. }
  33. // ParseExtClient - parses an extclient into a model
  34. func ParseExtClient(value string) (models.ExtClient, error) {
  35. var extClient models.ExtClient
  36. err := json.Unmarshal([]byte(value), &extClient)
  37. return extClient, err
  38. }
  39. // ParseIntClient - parses int client
  40. func ParseIntClient(value string) (models.IntClient, error) {
  41. var intClient models.IntClient
  42. err := json.Unmarshal([]byte(value), &intClient)
  43. return intClient, err
  44. }
  45. //Takes in an arbitrary field and value for field and checks to see if any other
  46. //node has that value for the same field within the network
  47. // SliceContains - sees if a slice contains something
  48. func SliceContains(slice []string, item string) bool {
  49. set := make(map[string]struct{}, len(slice))
  50. for _, s := range slice {
  51. set[s] = struct{}{}
  52. }
  53. _, ok := set[item]
  54. return ok
  55. }
  56. // GetPeersList - gets peers for given network
  57. func GetPeersList(networkName string) ([]models.PeersResponse, error) {
  58. var peers []models.PeersResponse
  59. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  60. if err != nil {
  61. return peers, err
  62. }
  63. for _, value := range collection {
  64. var peer models.PeersResponse
  65. err := json.Unmarshal([]byte(value), &peer)
  66. if err != nil {
  67. continue // try the rest
  68. }
  69. peers = append(peers, peer)
  70. }
  71. return peers, err
  72. }
  73. // GetIntPeersList - get int peers list
  74. func GetIntPeersList() ([]models.PeersResponse, error) {
  75. var peers []models.PeersResponse
  76. records, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
  77. if err != nil {
  78. return peers, err
  79. }
  80. // parse the peers
  81. for _, value := range records {
  82. var peer models.PeersResponse
  83. err := json.Unmarshal([]byte(value), &peer)
  84. if err != nil {
  85. log.Fatal(err)
  86. }
  87. // add the node to our node array
  88. //maybe better to just return this? But then that's just GetNodes...
  89. peers = append(peers, peer)
  90. }
  91. return peers, err
  92. }
  93. // GetServerIntClient - get server int client
  94. func GetServerIntClient() (*models.IntClient, error) {
  95. intClients, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
  96. for _, value := range intClients {
  97. var intClient models.IntClient
  98. err = json.Unmarshal([]byte(value), &intClient)
  99. if err != nil {
  100. return nil, err
  101. }
  102. if intClient.IsServer == "yes" && intClient.Network == "comms" {
  103. return &intClient, nil
  104. }
  105. }
  106. return nil, err
  107. }
  108. // NetworkExists - check if network exists
  109. func NetworkExists(name string) (bool, error) {
  110. var network string
  111. var err error
  112. if network, err = database.FetchRecord(database.NETWORKS_TABLE_NAME, name); err != nil {
  113. return false, err
  114. }
  115. return len(network) > 0, nil
  116. }
  117. // NetworkNodesUpdateAction - updates action of network nodes
  118. func NetworkNodesUpdateAction(networkName string, action string) error {
  119. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  120. if err != nil {
  121. if database.IsEmptyRecord(err) {
  122. return nil
  123. }
  124. return err
  125. }
  126. for _, value := range collections {
  127. var node models.Node
  128. err := json.Unmarshal([]byte(value), &node)
  129. if err != nil {
  130. fmt.Println("error in node address assignment!")
  131. return err
  132. }
  133. if action == models.NODE_UPDATE_KEY && node.IsStatic == "yes" {
  134. continue
  135. }
  136. if node.Network == networkName {
  137. node.Action = action
  138. data, err := json.Marshal(&node)
  139. if err != nil {
  140. return err
  141. }
  142. node.SetID()
  143. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  144. }
  145. }
  146. return nil
  147. }
  148. // NetworkNodesUpdatePullChanges - tells nodes on network to pull
  149. func NetworkNodesUpdatePullChanges(networkName string) error {
  150. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  151. if err != nil {
  152. if database.IsEmptyRecord(err) {
  153. return nil
  154. }
  155. return err
  156. }
  157. for _, value := range collections {
  158. var node models.Node
  159. err := json.Unmarshal([]byte(value), &node)
  160. if err != nil {
  161. fmt.Println("error in node address assignment!")
  162. return err
  163. }
  164. if node.Network == networkName {
  165. node.PullChanges = "yes"
  166. data, err := json.Marshal(&node)
  167. if err != nil {
  168. return err
  169. }
  170. node.SetID()
  171. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  172. }
  173. }
  174. return nil
  175. }
  176. // IsNetworkDisplayNameUnique - checks if network display name unique
  177. func IsNetworkDisplayNameUnique(name string) (bool, error) {
  178. isunique := true
  179. dbs, err := logic.GetNetworks()
  180. if err != nil {
  181. return database.IsEmptyRecord(err), err
  182. }
  183. for i := 0; i < len(dbs); i++ {
  184. if name == dbs[i].DisplayName {
  185. isunique = false
  186. }
  187. }
  188. return isunique, nil
  189. }
  190. // IsMacAddressUnique - checks if mac is unique
  191. func IsMacAddressUnique(macaddress string, networkName string) (bool, error) {
  192. _, err := database.FetchRecord(database.NODES_TABLE_NAME, macaddress+"###"+networkName)
  193. if err != nil {
  194. return database.IsEmptyRecord(err), err
  195. }
  196. return true, nil
  197. }
  198. // GetNetworkNonServerNodeCount - get number of network non server nodes
  199. func GetNetworkNonServerNodeCount(networkName string) (int, error) {
  200. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  201. count := 0
  202. if err != nil && !database.IsEmptyRecord(err) {
  203. return count, err
  204. }
  205. for _, value := range collection {
  206. var node models.Node
  207. if err = json.Unmarshal([]byte(value), &node); err != nil {
  208. return count, err
  209. } else {
  210. if node.Network == networkName && node.IsServer != "yes" {
  211. count++
  212. }
  213. }
  214. }
  215. return count, nil
  216. }
  217. // IsKeyValidGlobal - checks if a key is valid globally
  218. func IsKeyValidGlobal(keyvalue string) bool {
  219. networks, _ := logic.GetNetworks()
  220. var key models.AccessKey
  221. foundkey := false
  222. isvalid := false
  223. for _, network := range networks {
  224. for i := len(network.AccessKeys) - 1; i >= 0; i-- {
  225. currentkey := network.AccessKeys[i]
  226. if currentkey.Value == keyvalue {
  227. key = currentkey
  228. foundkey = true
  229. break
  230. }
  231. }
  232. if foundkey {
  233. break
  234. }
  235. }
  236. if foundkey {
  237. if key.Uses > 0 {
  238. isvalid = true
  239. }
  240. }
  241. return isvalid
  242. }
  243. //TODO: Contains a fatal error return. Need to change
  244. //This just gets a network object from a network name
  245. //Should probably just be GetNetwork. kind of a dumb name.
  246. //Used in contexts where it's not the Parent network.
  247. //Similar to above but checks if Cidr range is valid
  248. //At least this guy's got some print statements
  249. //still not good error handling
  250. //This checks to make sure a network name is valid.
  251. //Switch to REGEX?
  252. // NameInNetworkCharSet - see if name is in charset for networks
  253. func NameInNetworkCharSet(name string) bool {
  254. charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
  255. for _, char := range name {
  256. if !strings.Contains(charset, strings.ToLower(string(char))) {
  257. return false
  258. }
  259. }
  260. return true
  261. }
  262. // NameInDNSCharSet - name in dns char set
  263. func NameInDNSCharSet(name string) bool {
  264. charset := "abcdefghijklmnopqrstuvwxyz1234567890-."
  265. for _, char := range name {
  266. if !strings.Contains(charset, strings.ToLower(string(char))) {
  267. return false
  268. }
  269. }
  270. return true
  271. }
  272. // NameInNodeCharSet - name in node char set
  273. func NameInNodeCharSet(name string) bool {
  274. charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
  275. for _, char := range name {
  276. if !strings.Contains(charset, strings.ToLower(string(char))) {
  277. return false
  278. }
  279. }
  280. return true
  281. }
  282. // RemoveDeletedNode - remove deleted node
  283. func RemoveDeletedNode(nodeid string) bool {
  284. return database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, nodeid) == nil
  285. }
  286. // DeleteAllIntClients - delete all int clients
  287. func DeleteAllIntClients() error {
  288. err := database.DeleteAllRecords(database.INT_CLIENTS_TABLE_NAME)
  289. if err != nil {
  290. return err
  291. }
  292. return nil
  293. }
  294. // GetAllIntClients - get all int clients
  295. func GetAllIntClients() ([]models.IntClient, error) {
  296. var clients []models.IntClient
  297. collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
  298. if err != nil {
  299. return clients, err
  300. }
  301. for _, value := range collection {
  302. var client models.IntClient
  303. err := json.Unmarshal([]byte(value), &client)
  304. if err != nil {
  305. return []models.IntClient{}, err
  306. }
  307. // add node to our array
  308. clients = append(clients, client)
  309. }
  310. return clients, nil
  311. }
  312. // GetAllExtClients - get all ext clients
  313. func GetAllExtClients() ([]models.ExtClient, error) {
  314. var extclients []models.ExtClient
  315. collection, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
  316. if err != nil {
  317. return extclients, err
  318. }
  319. for _, value := range collection {
  320. var extclient models.ExtClient
  321. err := json.Unmarshal([]byte(value), &extclient)
  322. if err != nil {
  323. return []models.ExtClient{}, err
  324. }
  325. // add node to our array
  326. extclients = append(extclients, extclient)
  327. }
  328. return extclients, nil
  329. }
  330. // GenKey - generates access key
  331. func GenKey() string {
  332. var seededRand *rand.Rand = rand.New(
  333. rand.NewSource(time.Now().UnixNano()))
  334. length := 16
  335. charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  336. b := make([]byte, length)
  337. for i := range b {
  338. b[i] = charset[seededRand.Intn(len(charset))]
  339. }
  340. return string(b)
  341. }
  342. //generate a key value
  343. //we should probably just have 1 random string generator
  344. //that can be used across all functions
  345. //have a "base string" a "length" and a "charset"
  346. // GenKeyName - generates a key name
  347. func GenKeyName() string {
  348. var seededRand *rand.Rand = rand.New(
  349. rand.NewSource(time.Now().UnixNano()))
  350. length := 5
  351. charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  352. b := make([]byte, length)
  353. for i := range b {
  354. b[i] = charset[seededRand.Intn(len(charset))]
  355. }
  356. return "key" + string(b)
  357. }
  358. // IsIPUnique - checks if an IP is unique
  359. func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
  360. isunique := true
  361. collection, err := database.FetchRecords(tableName)
  362. if err != nil {
  363. return isunique
  364. }
  365. for _, value := range collection { // filter
  366. var node models.Node
  367. if err = json.Unmarshal([]byte(value), &node); err != nil {
  368. continue
  369. }
  370. if isIpv6 {
  371. if node.Address6 == ip && node.Network == network {
  372. return false
  373. }
  374. } else {
  375. if node.Address == ip && node.Network == network {
  376. return false
  377. }
  378. }
  379. }
  380. return isunique
  381. }
  382. // DeleteKey - deletes a key
  383. func DeleteKey(network models.Network, i int) {
  384. network.AccessKeys = append(network.AccessKeys[:i],
  385. network.AccessKeys[i+1:]...)
  386. if networkData, err := json.Marshal(&network); err != nil {
  387. return
  388. } else {
  389. database.Insert(network.NetID, string(networkData), database.NETWORKS_TABLE_NAME)
  390. }
  391. }