node.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. package models
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "math/rand"
  6. "net"
  7. "strings"
  8. "time"
  9. "github.com/go-playground/validator/v10"
  10. "github.com/gravitl/netmaker/database"
  11. "golang.org/x/crypto/bcrypt"
  12. )
  13. const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  14. const TEN_YEARS_IN_SECONDS = 300000000
  15. // == ACTIONS == (can only be set by GRPC)
  16. const NODE_UPDATE_KEY = "updatekey"
  17. const NODE_SERVER_NAME = "netmaker"
  18. const NODE_DELETE = "delete"
  19. const NODE_IS_PENDING = "pending"
  20. const NODE_NOOP = "noop"
  21. var seededRand *rand.Rand = rand.New(
  22. rand.NewSource(time.Now().UnixNano()))
  23. //node struct
  24. type Node struct {
  25. ID string `json:"id,omitempty" bson:"id,omitempty"`
  26. Address string `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
  27. Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
  28. LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
  29. Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=12,in_charset"`
  30. ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
  31. PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
  32. Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
  33. PostUp string `json:"postup" bson:"postup" yaml:"postup"`
  34. PostDown string `json:"postdown" bson:"postdown" yaml:"postdown"`
  35. AllowedIPs []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
  36. PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
  37. SaveConfig string `json:"saveconfig" bson:"saveconfig" yaml:"saveconfig" validate:"checkyesorno"`
  38. AccessKey string `json:"accesskey" bson:"accesskey" yaml:"accesskey"`
  39. Interface string `json:"interface" bson:"interface" yaml:"interface"`
  40. LastModified int64 `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"`
  41. KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp" yaml:"keyupdatetimestamp"`
  42. ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
  43. LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
  44. LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
  45. MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,mac,macaddress_unique"`
  46. CheckInInterval int32 `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"`
  47. Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`
  48. Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"`
  49. IsPending string `json:"ispending" bson:"ispending" yaml:"ispending"`
  50. IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway"`
  51. IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway"`
  52. EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
  53. IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
  54. IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"`
  55. UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
  56. PullChanges string `json:"pullchanges" bson:"pullchanges" yaml:"pullchanges" validate:"checkyesorno"`
  57. DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
  58. IsDualStack string `json:"isdualstack" bson:"isdualstack" yaml:"isdualstack" validate:"checkyesorno"`
  59. IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
  60. Action string `json:"action" bson:"action" yaml:"action"`
  61. IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
  62. LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"`
  63. Roaming string `json:"roaming" bson:"roaming" yaml:"roaming" validate:"checkyesorno"`
  64. IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
  65. }
  66. func (node *Node) SetDefaultAction() {
  67. if node.Action == "" {
  68. node.Action = NODE_NOOP
  69. }
  70. }
  71. func (node *Node) SetRoamingDefault() {
  72. if node.Roaming == "" {
  73. node.Roaming = "yes"
  74. }
  75. }
  76. func (node *Node) SetPullChangesDefault() {
  77. if node.PullChanges == "" {
  78. node.PullChanges = "no"
  79. }
  80. }
  81. func (node *Node) SetIPForwardingDefault() {
  82. if node.IPForwarding == "" {
  83. node.IPForwarding = "yes"
  84. }
  85. }
  86. func (node *Node) SetIsLocalDefault() {
  87. if node.IsLocal == "" {
  88. node.IsLocal = "no"
  89. }
  90. }
  91. func (node *Node) SetDNSOnDefault() {
  92. if node.DNSOn == "" {
  93. node.DNSOn = "no"
  94. }
  95. }
  96. func (node *Node) SetIsDualStackDefault() {
  97. if node.IsDualStack == "" {
  98. node.IsDualStack = "no"
  99. }
  100. }
  101. func (node *Node) SetIsServerDefault() {
  102. if node.IsServer != "yes" {
  103. node.IsServer = "no"
  104. }
  105. }
  106. func (node *Node) SetIsStaticDefault() {
  107. if node.IsServer == "yes" {
  108. node.IsStatic = "yes"
  109. } else if node.IsStatic != "yes" {
  110. node.IsStatic = "no"
  111. }
  112. }
  113. func (node *Node) SetLastModified() {
  114. node.LastModified = time.Now().Unix()
  115. }
  116. func (node *Node) SetLastCheckIn() {
  117. node.LastCheckIn = time.Now().Unix()
  118. }
  119. func (node *Node) SetLastPeerUpdate() {
  120. node.LastPeerUpdate = time.Now().Unix()
  121. }
  122. func (node *Node) SetID() {
  123. node.ID = node.MacAddress + "###" + node.Network
  124. }
  125. func (node *Node) SetExpirationDateTime() {
  126. node.ExpirationDateTime = time.Now().Unix() + TEN_YEARS_IN_SECONDS
  127. }
  128. func (node *Node) SetDefaultName() {
  129. if node.Name == "" {
  130. node.Name = GenerateNodeName()
  131. }
  132. }
  133. func (node *Node) CheckIsServer() bool {
  134. nodeData, err := database.FetchRecords(database.NODES_TABLE_NAME)
  135. if err != nil && !database.IsEmptyRecord(err) {
  136. return false
  137. }
  138. for _, value := range nodeData {
  139. var tmpNode Node
  140. if err := json.Unmarshal([]byte(value), &tmpNode); err != nil {
  141. continue
  142. }
  143. if tmpNode.Network == node.Network && tmpNode.MacAddress != node.MacAddress {
  144. return false
  145. }
  146. }
  147. return true
  148. }
  149. func (node *Node) GetNetwork() (Network, error) {
  150. var network Network
  151. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
  152. if err != nil {
  153. return network, err
  154. }
  155. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  156. return Network{}, err
  157. }
  158. return network, nil
  159. }
  160. //TODO: I dont know why this exists
  161. //This should exist on the node.go struct. I'm sure there was a reason?
  162. func (node *Node) SetDefaults() {
  163. //TODO: Maybe I should make Network a part of the node struct. Then we can just query the Network object for stuff.
  164. parentNetwork, _ := node.GetNetwork()
  165. node.ExpirationDateTime = time.Now().Unix() + TEN_YEARS_IN_SECONDS
  166. if node.ListenPort == 0 {
  167. node.ListenPort = parentNetwork.DefaultListenPort
  168. }
  169. if node.SaveConfig == "" {
  170. if parentNetwork.DefaultSaveConfig != "" {
  171. node.SaveConfig = parentNetwork.DefaultSaveConfig
  172. } else {
  173. node.SaveConfig = "yes"
  174. }
  175. }
  176. if node.Interface == "" {
  177. node.Interface = parentNetwork.DefaultInterface
  178. }
  179. if node.PersistentKeepalive == 0 {
  180. node.PersistentKeepalive = parentNetwork.DefaultKeepalive
  181. }
  182. if node.PostUp == "" {
  183. postup := parentNetwork.DefaultPostUp
  184. node.PostUp = postup
  185. }
  186. if node.IsStatic == "" {
  187. node.IsStatic = "no"
  188. }
  189. if node.UDPHolePunch == "" {
  190. node.UDPHolePunch = parentNetwork.DefaultUDPHolePunch
  191. if node.UDPHolePunch == "" {
  192. node.UDPHolePunch = "yes"
  193. }
  194. }
  195. node.CheckInInterval = parentNetwork.DefaultCheckInInterval
  196. node.SetIPForwardingDefault()
  197. node.SetDNSOnDefault()
  198. node.SetIsLocalDefault()
  199. node.SetIsDualStackDefault()
  200. node.SetLastModified()
  201. node.SetDefaultName()
  202. node.SetLastCheckIn()
  203. node.SetLastPeerUpdate()
  204. node.SetRoamingDefault()
  205. node.SetPullChangesDefault()
  206. node.SetDefaultAction()
  207. node.SetID()
  208. node.SetIsServerDefault()
  209. node.SetIsStaticDefault()
  210. node.KeyUpdateTimeStamp = time.Now().Unix()
  211. }
  212. func (newNode *Node) Fill(currentNode *Node) {
  213. if newNode.ID == "" {
  214. newNode.ID = currentNode.ID
  215. }
  216. if newNode.Address == "" && newNode.IsStatic != "yes"{
  217. newNode.Address = currentNode.Address
  218. }
  219. if newNode.Address6 == "" && newNode.IsStatic != "yes"{
  220. newNode.Address6 = currentNode.Address6
  221. }
  222. if newNode.LocalAddress == "" {
  223. newNode.LocalAddress = currentNode.LocalAddress
  224. }
  225. if newNode.Name == "" {
  226. newNode.Name = currentNode.Name
  227. }
  228. if newNode.ListenPort == 0 && newNode.IsStatic != "yes"{
  229. newNode.ListenPort = currentNode.ListenPort
  230. }
  231. if newNode.PublicKey == "" && newNode.IsStatic != "yes" {
  232. newNode.PublicKey = currentNode.PublicKey
  233. } else {
  234. newNode.KeyUpdateTimeStamp = time.Now().Unix()
  235. }
  236. if newNode.Endpoint == "" && newNode.IsStatic != "yes"{
  237. newNode.Endpoint = currentNode.Endpoint
  238. }
  239. if newNode.PostUp == "" {
  240. newNode.PostUp = currentNode.PostUp
  241. }
  242. if newNode.PostDown == "" {
  243. newNode.PostDown = currentNode.PostDown
  244. }
  245. if newNode.AllowedIPs == nil {
  246. newNode.AllowedIPs = currentNode.AllowedIPs
  247. }
  248. if newNode.PersistentKeepalive == 0 {
  249. newNode.PersistentKeepalive = currentNode.PersistentKeepalive
  250. }
  251. if newNode.SaveConfig == "" {
  252. newNode.SaveConfig = currentNode.SaveConfig
  253. }
  254. if newNode.AccessKey == "" {
  255. newNode.AccessKey = currentNode.AccessKey
  256. }
  257. if newNode.Interface == "" {
  258. newNode.Interface = currentNode.Interface
  259. }
  260. if newNode.LastModified == 0 {
  261. newNode.LastModified = currentNode.LastModified
  262. }
  263. if newNode.KeyUpdateTimeStamp == 0 {
  264. newNode.LastModified = currentNode.LastModified
  265. }
  266. if newNode.ExpirationDateTime == 0 {
  267. newNode.ExpirationDateTime = currentNode.ExpirationDateTime
  268. }
  269. if newNode.LastPeerUpdate == 0 {
  270. newNode.LastPeerUpdate = currentNode.LastPeerUpdate
  271. }
  272. if newNode.LastCheckIn == 0 {
  273. newNode.LastCheckIn = currentNode.LastCheckIn
  274. }
  275. if newNode.MacAddress == "" {
  276. newNode.MacAddress = currentNode.MacAddress
  277. }
  278. if newNode.CheckInInterval == 0 {
  279. newNode.CheckInInterval = currentNode.CheckInInterval
  280. }
  281. if newNode.Password != "" {
  282. err := bcrypt.CompareHashAndPassword([]byte(newNode.Password), []byte(currentNode.Password))
  283. if err != nil && currentNode.Password != newNode.Password {
  284. hash, err := bcrypt.GenerateFromPassword([]byte(newNode.Password), 5)
  285. if err == nil {
  286. newNode.Password = string(hash)
  287. }
  288. }
  289. } else {
  290. newNode.Password = currentNode.Password
  291. }
  292. if newNode.Network == "" {
  293. newNode.Network = currentNode.Network
  294. }
  295. if newNode.IsPending == "" {
  296. newNode.IsPending = currentNode.IsPending
  297. }
  298. if newNode.IsEgressGateway == "" {
  299. newNode.IsEgressGateway = currentNode.IsEgressGateway
  300. }
  301. if newNode.IsIngressGateway == "" {
  302. newNode.IsIngressGateway = currentNode.IsIngressGateway
  303. }
  304. if newNode.EgressGatewayRanges == nil {
  305. newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
  306. }
  307. if newNode.IngressGatewayRange == "" {
  308. newNode.IngressGatewayRange = currentNode.IngressGatewayRange
  309. }
  310. if newNode.IsStatic == "" {
  311. newNode.IsStatic = currentNode.IsStatic
  312. }
  313. if newNode.UDPHolePunch == "" {
  314. newNode.UDPHolePunch = currentNode.SaveConfig
  315. }
  316. if newNode.DNSOn == "" {
  317. newNode.DNSOn = currentNode.DNSOn
  318. }
  319. if newNode.IsDualStack == "" {
  320. newNode.IsDualStack = currentNode.IsDualStack
  321. }
  322. if newNode.IsLocal == "" {
  323. newNode.IsLocal = currentNode.IsLocal
  324. }
  325. if newNode.IPForwarding == "" {
  326. newNode.IPForwarding = currentNode.IPForwarding
  327. }
  328. if newNode.PullChanges == "" {
  329. newNode.PullChanges = currentNode.PullChanges
  330. }
  331. if newNode.Roaming == "" {
  332. newNode.Roaming = currentNode.Roaming
  333. }
  334. if newNode.Action == "" {
  335. newNode.Action = currentNode.Action
  336. }
  337. newNode.IsServer = currentNode.IsServer
  338. if newNode.IsServer == "yes" {
  339. newNode.IsStatic = "yes"
  340. }
  341. }
  342. func (currentNode *Node) Update(newNode *Node) error {
  343. newNode.Fill(currentNode)
  344. if err := newNode.Validate(true); err != nil {
  345. return err
  346. }
  347. newNode.SetID()
  348. if newNode.ID == currentNode.ID {
  349. newNode.SetLastModified()
  350. if data, err := json.Marshal(newNode); err != nil {
  351. return err
  352. } else {
  353. return database.Insert(newNode.ID, string(data), database.NODES_TABLE_NAME)
  354. }
  355. }
  356. return errors.New("failed to update node " + newNode.MacAddress + ", cannot change macaddress.")
  357. }
  358. func StringWithCharset(length int, charset string) string {
  359. b := make([]byte, length)
  360. for i := range b {
  361. b[i] = charset[seededRand.Intn(len(charset))]
  362. }
  363. return string(b)
  364. }
  365. //Check for valid IPv4 address
  366. //Note: We dont handle IPv6 AT ALL!!!!! This definitely is needed at some point
  367. //But for iteration 1, lets just stick to IPv4. Keep it simple stupid.
  368. func IsIpv4Net(host string) bool {
  369. return net.ParseIP(host) != nil
  370. }
  371. func (node *Node) Validate(isUpdate bool) error {
  372. v := validator.New()
  373. _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
  374. if isUpdate {
  375. return true
  376. }
  377. isFieldUnique, _ := node.IsIDUnique()
  378. return isFieldUnique
  379. })
  380. _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
  381. _, err := node.GetNetwork()
  382. return err == nil
  383. })
  384. _ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool {
  385. isgood := node.NameInNodeCharSet()
  386. return isgood
  387. })
  388. _ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
  389. return CheckYesOrNo(fl)
  390. })
  391. err := v.Struct(node)
  392. return err
  393. }
  394. func (node *Node) IsIDUnique() (bool, error) {
  395. _, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
  396. return database.IsEmptyRecord(err), err
  397. }
  398. func (node *Node) NameInNodeCharSet() bool {
  399. charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
  400. for _, char := range node.Name {
  401. if !strings.Contains(charset, strings.ToLower(string(char))) {
  402. return false
  403. }
  404. }
  405. return true
  406. }
  407. func GetAllNodes() ([]Node, error) {
  408. var nodes []Node
  409. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  410. if err != nil {
  411. if database.IsEmptyRecord(err) {
  412. return []Node{}, nil
  413. }
  414. return []Node{}, err
  415. }
  416. for _, value := range collection {
  417. var node Node
  418. if err := json.Unmarshal([]byte(value), &node); err != nil {
  419. return []Node{}, err
  420. }
  421. // add node to our array
  422. nodes = append(nodes, node)
  423. }
  424. return nodes, nil
  425. }
  426. func GetNode(macaddress string, network string) (Node, error) {
  427. var node Node
  428. key, err := GetID(macaddress, network)
  429. if err != nil {
  430. return node, err
  431. }
  432. data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
  433. if err != nil {
  434. return node, err
  435. }
  436. if err = json.Unmarshal([]byte(data), &node); err != nil {
  437. return node, err
  438. }
  439. return node, err
  440. }
  441. func GetID(macaddress string, network string) (string, error) {
  442. if macaddress == "" || network == "" {
  443. return "", errors.New("unable to get record key")
  444. }
  445. return macaddress + "###" + network, nil
  446. }