node.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  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) SetDefaulIsPending() {
  67. if node.IsPending == "" {
  68. node.IsPending = "no"
  69. }
  70. }
  71. func (node *Node) SetDefaultEgressGateway() {
  72. if node.IsEgressGateway == "" {
  73. node.IsEgressGateway = "no"
  74. }
  75. }
  76. func (node *Node) SetDefaultIngressGateway() {
  77. if node.IsIngressGateway == "" {
  78. node.IsIngressGateway = "no"
  79. }
  80. }
  81. func (node *Node) SetDefaultAction() {
  82. if node.Action == "" {
  83. node.Action = NODE_NOOP
  84. }
  85. }
  86. func (node *Node) SetRoamingDefault() {
  87. if node.Roaming == "" {
  88. node.Roaming = "yes"
  89. }
  90. }
  91. func (node *Node) SetPullChangesDefault() {
  92. if node.PullChanges == "" {
  93. node.PullChanges = "no"
  94. }
  95. }
  96. func (node *Node) SetIPForwardingDefault() {
  97. if node.IPForwarding == "" {
  98. node.IPForwarding = "yes"
  99. }
  100. }
  101. func (node *Node) SetIsLocalDefault() {
  102. if node.IsLocal == "" {
  103. node.IsLocal = "no"
  104. }
  105. }
  106. func (node *Node) SetDNSOnDefault() {
  107. if node.DNSOn == "" {
  108. node.DNSOn = "no"
  109. }
  110. }
  111. func (node *Node) SetIsDualStackDefault() {
  112. if node.IsDualStack == "" {
  113. node.IsDualStack = "no"
  114. }
  115. }
  116. func (node *Node) SetIsServerDefault() {
  117. if node.IsServer != "yes" {
  118. node.IsServer = "no"
  119. }
  120. }
  121. func (node *Node) SetIsStaticDefault() {
  122. if node.IsServer == "yes" {
  123. node.IsStatic = "yes"
  124. } else if node.IsStatic != "yes" {
  125. node.IsStatic = "no"
  126. }
  127. }
  128. func (node *Node) SetLastModified() {
  129. node.LastModified = time.Now().Unix()
  130. }
  131. func (node *Node) SetLastCheckIn() {
  132. node.LastCheckIn = time.Now().Unix()
  133. }
  134. func (node *Node) SetLastPeerUpdate() {
  135. node.LastPeerUpdate = time.Now().Unix()
  136. }
  137. func (node *Node) SetID() {
  138. node.ID = node.MacAddress + "###" + node.Network
  139. }
  140. func (node *Node) SetExpirationDateTime() {
  141. node.ExpirationDateTime = time.Now().Unix() + TEN_YEARS_IN_SECONDS
  142. }
  143. func (node *Node) SetDefaultName() {
  144. if node.Name == "" {
  145. node.Name = GenerateNodeName()
  146. }
  147. }
  148. func (node *Node) CheckIsServer() bool {
  149. nodeData, err := database.FetchRecords(database.NODES_TABLE_NAME)
  150. if err != nil && !database.IsEmptyRecord(err) {
  151. return false
  152. }
  153. for _, value := range nodeData {
  154. var tmpNode Node
  155. if err := json.Unmarshal([]byte(value), &tmpNode); err != nil {
  156. continue
  157. }
  158. if tmpNode.Network == node.Network && tmpNode.MacAddress != node.MacAddress {
  159. return false
  160. }
  161. }
  162. return true
  163. }
  164. func (node *Node) GetNetwork() (Network, error) {
  165. var network Network
  166. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
  167. if err != nil {
  168. return network, err
  169. }
  170. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  171. return Network{}, err
  172. }
  173. return network, nil
  174. }
  175. //TODO: I dont know why this exists
  176. //This should exist on the node.go struct. I'm sure there was a reason?
  177. func (node *Node) SetDefaults() {
  178. //TODO: Maybe I should make Network a part of the node struct. Then we can just query the Network object for stuff.
  179. parentNetwork, _ := node.GetNetwork()
  180. node.ExpirationDateTime = time.Now().Unix() + TEN_YEARS_IN_SECONDS
  181. if node.ListenPort == 0 {
  182. node.ListenPort = parentNetwork.DefaultListenPort
  183. }
  184. if node.SaveConfig == "" {
  185. if parentNetwork.DefaultSaveConfig != "" {
  186. node.SaveConfig = parentNetwork.DefaultSaveConfig
  187. } else {
  188. node.SaveConfig = "yes"
  189. }
  190. }
  191. if node.Interface == "" {
  192. node.Interface = parentNetwork.DefaultInterface
  193. }
  194. if node.PersistentKeepalive == 0 {
  195. node.PersistentKeepalive = parentNetwork.DefaultKeepalive
  196. }
  197. if node.PostUp == "" {
  198. postup := parentNetwork.DefaultPostUp
  199. node.PostUp = postup
  200. }
  201. if node.IsStatic == "" {
  202. node.IsStatic = "no"
  203. }
  204. if node.UDPHolePunch == "" {
  205. node.UDPHolePunch = parentNetwork.DefaultUDPHolePunch
  206. if node.UDPHolePunch == "" {
  207. node.UDPHolePunch = "yes"
  208. }
  209. }
  210. node.CheckInInterval = parentNetwork.DefaultCheckInInterval
  211. node.SetIPForwardingDefault()
  212. node.SetDNSOnDefault()
  213. node.SetIsLocalDefault()
  214. node.SetIsDualStackDefault()
  215. node.SetLastModified()
  216. node.SetDefaultName()
  217. node.SetLastCheckIn()
  218. node.SetLastPeerUpdate()
  219. node.SetRoamingDefault()
  220. node.SetPullChangesDefault()
  221. node.SetDefaultAction()
  222. node.SetID()
  223. node.SetIsServerDefault()
  224. node.SetIsStaticDefault()
  225. node.SetDefaultEgressGateway()
  226. node.SetDefaultIngressGateway()
  227. node.SetDefaulIsPending()
  228. node.KeyUpdateTimeStamp = time.Now().Unix()
  229. }
  230. func (newNode *Node) Fill(currentNode *Node) {
  231. if newNode.ID == "" {
  232. newNode.ID = currentNode.ID
  233. }
  234. if newNode.Address == "" && newNode.IsStatic != "yes" {
  235. newNode.Address = currentNode.Address
  236. }
  237. if newNode.Address6 == "" && newNode.IsStatic != "yes" {
  238. newNode.Address6 = currentNode.Address6
  239. }
  240. if newNode.LocalAddress == "" {
  241. newNode.LocalAddress = currentNode.LocalAddress
  242. }
  243. if newNode.Name == "" {
  244. newNode.Name = currentNode.Name
  245. }
  246. if newNode.ListenPort == 0 && newNode.IsStatic != "yes" {
  247. newNode.ListenPort = currentNode.ListenPort
  248. }
  249. if newNode.PublicKey == "" && newNode.IsStatic != "yes" {
  250. newNode.PublicKey = currentNode.PublicKey
  251. } else {
  252. newNode.KeyUpdateTimeStamp = time.Now().Unix()
  253. }
  254. if newNode.Endpoint == "" && newNode.IsStatic != "yes" {
  255. newNode.Endpoint = currentNode.Endpoint
  256. }
  257. if newNode.PostUp == "" {
  258. newNode.PostUp = currentNode.PostUp
  259. }
  260. if newNode.PostDown == "" {
  261. newNode.PostDown = currentNode.PostDown
  262. }
  263. if newNode.AllowedIPs == nil {
  264. newNode.AllowedIPs = currentNode.AllowedIPs
  265. }
  266. if newNode.PersistentKeepalive == 0 {
  267. newNode.PersistentKeepalive = currentNode.PersistentKeepalive
  268. }
  269. if newNode.SaveConfig == "" {
  270. newNode.SaveConfig = currentNode.SaveConfig
  271. }
  272. if newNode.AccessKey == "" {
  273. newNode.AccessKey = currentNode.AccessKey
  274. }
  275. if newNode.Interface == "" {
  276. newNode.Interface = currentNode.Interface
  277. }
  278. if newNode.LastModified == 0 {
  279. newNode.LastModified = currentNode.LastModified
  280. }
  281. if newNode.KeyUpdateTimeStamp == 0 {
  282. newNode.LastModified = currentNode.LastModified
  283. }
  284. if newNode.ExpirationDateTime == 0 {
  285. newNode.ExpirationDateTime = currentNode.ExpirationDateTime
  286. }
  287. if newNode.LastPeerUpdate == 0 {
  288. newNode.LastPeerUpdate = currentNode.LastPeerUpdate
  289. }
  290. if newNode.LastCheckIn == 0 {
  291. newNode.LastCheckIn = currentNode.LastCheckIn
  292. }
  293. if newNode.MacAddress == "" {
  294. newNode.MacAddress = currentNode.MacAddress
  295. }
  296. if newNode.CheckInInterval == 0 {
  297. newNode.CheckInInterval = currentNode.CheckInInterval
  298. }
  299. if newNode.Password != "" {
  300. err := bcrypt.CompareHashAndPassword([]byte(newNode.Password), []byte(currentNode.Password))
  301. if err != nil && currentNode.Password != newNode.Password {
  302. hash, err := bcrypt.GenerateFromPassword([]byte(newNode.Password), 5)
  303. if err == nil {
  304. newNode.Password = string(hash)
  305. }
  306. }
  307. } else {
  308. newNode.Password = currentNode.Password
  309. }
  310. if newNode.Network == "" {
  311. newNode.Network = currentNode.Network
  312. }
  313. if newNode.IsPending == "" {
  314. newNode.IsPending = currentNode.IsPending
  315. }
  316. if newNode.IsEgressGateway == "" {
  317. newNode.IsEgressGateway = currentNode.IsEgressGateway
  318. }
  319. if newNode.IsIngressGateway == "" {
  320. newNode.IsIngressGateway = currentNode.IsIngressGateway
  321. }
  322. if newNode.EgressGatewayRanges == nil {
  323. newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
  324. }
  325. if newNode.IngressGatewayRange == "" {
  326. newNode.IngressGatewayRange = currentNode.IngressGatewayRange
  327. }
  328. if newNode.IsStatic == "" {
  329. newNode.IsStatic = currentNode.IsStatic
  330. }
  331. if newNode.UDPHolePunch == "" {
  332. newNode.UDPHolePunch = currentNode.SaveConfig
  333. }
  334. if newNode.DNSOn == "" {
  335. newNode.DNSOn = currentNode.DNSOn
  336. }
  337. if newNode.IsDualStack == "" {
  338. newNode.IsDualStack = currentNode.IsDualStack
  339. }
  340. if newNode.IsLocal == "" {
  341. newNode.IsLocal = currentNode.IsLocal
  342. }
  343. if newNode.IPForwarding == "" {
  344. newNode.IPForwarding = currentNode.IPForwarding
  345. }
  346. if newNode.PullChanges == "" {
  347. newNode.PullChanges = currentNode.PullChanges
  348. }
  349. if newNode.Roaming == "" {
  350. newNode.Roaming = currentNode.Roaming
  351. }
  352. if newNode.Action == "" {
  353. newNode.Action = currentNode.Action
  354. }
  355. newNode.IsServer = currentNode.IsServer
  356. if newNode.IsServer == "yes" {
  357. newNode.IsStatic = "yes"
  358. }
  359. }
  360. func (currentNode *Node) Update(newNode *Node) error {
  361. newNode.Fill(currentNode)
  362. if err := newNode.Validate(true); err != nil {
  363. return err
  364. }
  365. newNode.SetID()
  366. if newNode.ID == currentNode.ID {
  367. newNode.SetLastModified()
  368. if data, err := json.Marshal(newNode); err != nil {
  369. return err
  370. } else {
  371. return database.Insert(newNode.ID, string(data), database.NODES_TABLE_NAME)
  372. }
  373. }
  374. return errors.New("failed to update node " + newNode.MacAddress + ", cannot change macaddress.")
  375. }
  376. func StringWithCharset(length int, charset string) string {
  377. b := make([]byte, length)
  378. for i := range b {
  379. b[i] = charset[seededRand.Intn(len(charset))]
  380. }
  381. return string(b)
  382. }
  383. //Check for valid IPv4 address
  384. //Note: We dont handle IPv6 AT ALL!!!!! This definitely is needed at some point
  385. //But for iteration 1, lets just stick to IPv4. Keep it simple stupid.
  386. func IsIpv4Net(host string) bool {
  387. return net.ParseIP(host) != nil
  388. }
  389. func (node *Node) Validate(isUpdate bool) error {
  390. v := validator.New()
  391. _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
  392. if isUpdate {
  393. return true
  394. }
  395. isFieldUnique, _ := node.IsIDUnique()
  396. return isFieldUnique
  397. })
  398. _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
  399. _, err := node.GetNetwork()
  400. return err == nil
  401. })
  402. _ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool {
  403. isgood := node.NameInNodeCharSet()
  404. return isgood
  405. })
  406. _ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
  407. return CheckYesOrNo(fl)
  408. })
  409. err := v.Struct(node)
  410. return err
  411. }
  412. func (node *Node) IsIDUnique() (bool, error) {
  413. _, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
  414. return database.IsEmptyRecord(err), err
  415. }
  416. func (node *Node) NameInNodeCharSet() bool {
  417. charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
  418. for _, char := range node.Name {
  419. if !strings.Contains(charset, strings.ToLower(string(char))) {
  420. return false
  421. }
  422. }
  423. return true
  424. }
  425. func GetAllNodes() ([]Node, error) {
  426. var nodes []Node
  427. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  428. if err != nil {
  429. if database.IsEmptyRecord(err) {
  430. return []Node{}, nil
  431. }
  432. return []Node{}, err
  433. }
  434. for _, value := range collection {
  435. var node Node
  436. if err := json.Unmarshal([]byte(value), &node); err != nil {
  437. return []Node{}, err
  438. }
  439. // add node to our array
  440. nodes = append(nodes, node)
  441. }
  442. return nodes, nil
  443. }
  444. func GetNode(macaddress string, network string) (Node, error) {
  445. var node Node
  446. key, err := GetID(macaddress, network)
  447. if err != nil {
  448. return node, err
  449. }
  450. data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
  451. if err != nil {
  452. return node, err
  453. }
  454. if err = json.Unmarshal([]byte(data), &node); err != nil {
  455. return node, err
  456. }
  457. return node, err
  458. }
  459. func GetID(macaddress string, network string) (string, error) {
  460. if macaddress == "" || network == "" {
  461. return "", errors.New("unable to get record key")
  462. }
  463. return macaddress + "###" + network, nil
  464. }