networks.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. package logic
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "os/exec"
  8. "strings"
  9. "github.com/go-playground/validator/v10"
  10. "github.com/gravitl/netmaker/database"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/netclient/ncutils"
  13. "github.com/gravitl/netmaker/validation"
  14. )
  15. // GetNetworks - returns all networks from database
  16. func GetNetworks() ([]models.Network, error) {
  17. var networks []models.Network
  18. collection, err := database.FetchRecords(database.NETWORKS_TABLE_NAME)
  19. if err != nil {
  20. return networks, err
  21. }
  22. for _, value := range collection {
  23. var network models.Network
  24. if err := json.Unmarshal([]byte(value), &network); err != nil {
  25. return networks, err
  26. }
  27. // add network our array
  28. networks = append(networks, network)
  29. }
  30. return networks, err
  31. }
  32. // GetParentNetwork - get parent network
  33. func GetParentNetwork(networkname string) (models.Network, error) {
  34. var network models.Network
  35. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
  36. if err != nil {
  37. return network, err
  38. }
  39. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  40. return models.Network{}, err
  41. }
  42. return network, nil
  43. }
  44. // UniqueAddress - see if address is unique
  45. func UniqueAddress(networkName string) (string, error) {
  46. var network models.Network
  47. network, err := GetParentNetwork(networkName)
  48. if err != nil {
  49. fmt.Println("UniqueAddress encountered an error")
  50. return "666", err
  51. }
  52. offset := true
  53. ip, ipnet, err := net.ParseCIDR(network.AddressRange)
  54. if err != nil {
  55. fmt.Println("UniqueAddress encountered an error")
  56. return "666", err
  57. }
  58. for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
  59. if offset {
  60. offset = false
  61. continue
  62. }
  63. if networkName == "comms" {
  64. if IsIPUnique(networkName, ip.String(), database.INT_CLIENTS_TABLE_NAME, false) {
  65. return ip.String(), err
  66. }
  67. } else {
  68. if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, false) && IsIPUnique(networkName, ip.String(), database.EXT_CLIENT_TABLE_NAME, false) {
  69. return ip.String(), err
  70. }
  71. }
  72. }
  73. //TODO
  74. err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
  75. return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
  76. }
  77. // IsIPUnique - checks if an IP is unique
  78. func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
  79. isunique := true
  80. collection, err := database.FetchRecords(tableName)
  81. if err != nil {
  82. return isunique
  83. }
  84. for _, value := range collection { // filter
  85. var node models.Node
  86. if err = json.Unmarshal([]byte(value), &node); err != nil {
  87. continue
  88. }
  89. if isIpv6 {
  90. if node.Address6 == ip && node.Network == network {
  91. return false
  92. }
  93. } else {
  94. if node.Address == ip && node.Network == network {
  95. return false
  96. }
  97. }
  98. }
  99. return isunique
  100. }
  101. // UniqueAddress6 - see if ipv6 address is unique
  102. func UniqueAddress6(networkName string) (string, error) {
  103. var network models.Network
  104. network, err := GetParentNetwork(networkName)
  105. if err != nil {
  106. fmt.Println("Network Not Found")
  107. return "", err
  108. }
  109. if network.IsDualStack == "no" {
  110. return "", nil
  111. }
  112. offset := true
  113. ip, ipnet, err := net.ParseCIDR(network.AddressRange6)
  114. if err != nil {
  115. fmt.Println("UniqueAddress6 encountered an error")
  116. return "666", err
  117. }
  118. for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
  119. if offset {
  120. offset = false
  121. continue
  122. }
  123. if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, true) {
  124. return ip.String(), err
  125. }
  126. }
  127. //TODO
  128. err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
  129. return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
  130. }
  131. // GetLocalIP - gets the local ip
  132. func GetLocalIP(node models.Node) string {
  133. var local string
  134. ifaces, err := net.Interfaces()
  135. if err != nil {
  136. return local
  137. }
  138. _, localrange, err := net.ParseCIDR(node.LocalRange)
  139. if err != nil {
  140. return local
  141. }
  142. found := false
  143. for _, i := range ifaces {
  144. if i.Flags&net.FlagUp == 0 {
  145. continue // interface down
  146. }
  147. if i.Flags&net.FlagLoopback != 0 {
  148. continue // loopback interface
  149. }
  150. addrs, err := i.Addrs()
  151. if err != nil {
  152. return local
  153. }
  154. for _, addr := range addrs {
  155. var ip net.IP
  156. switch v := addr.(type) {
  157. case *net.IPNet:
  158. if !found {
  159. ip = v.IP
  160. local = ip.String()
  161. if node.IsLocal == "yes" {
  162. found = localrange.Contains(ip)
  163. } else {
  164. found = true
  165. }
  166. }
  167. case *net.IPAddr:
  168. if !found {
  169. ip = v.IP
  170. local = ip.String()
  171. if node.IsLocal == "yes" {
  172. found = localrange.Contains(ip)
  173. } else {
  174. found = true
  175. }
  176. }
  177. }
  178. }
  179. }
  180. return local
  181. }
  182. // UpdateNetworkLocalAddresses - updates network localaddresses
  183. func UpdateNetworkLocalAddresses(networkName string) error {
  184. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  185. if err != nil {
  186. return err
  187. }
  188. for _, value := range collection {
  189. var node models.Node
  190. err := json.Unmarshal([]byte(value), &node)
  191. if err != nil {
  192. fmt.Println("error in node address assignment!")
  193. return err
  194. }
  195. if node.Network == networkName {
  196. ipaddr, iperr := UniqueAddress(networkName)
  197. if iperr != nil {
  198. fmt.Println("error in node address assignment!")
  199. return iperr
  200. }
  201. node.Address = ipaddr
  202. newNodeData, err := json.Marshal(&node)
  203. if err != nil {
  204. fmt.Println("error in node address assignment!")
  205. return err
  206. }
  207. node.SetID()
  208. database.Insert(node.ID, string(newNodeData), database.NODES_TABLE_NAME)
  209. }
  210. }
  211. return nil
  212. }
  213. // UpdateNetworkNodeAddresses - updates network node addresses
  214. func UpdateNetworkNodeAddresses(networkName string) error {
  215. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  216. if err != nil {
  217. return err
  218. }
  219. for _, value := range collections {
  220. var node models.Node
  221. err := json.Unmarshal([]byte(value), &node)
  222. if err != nil {
  223. fmt.Println("error in node address assignment!")
  224. return err
  225. }
  226. if node.Network == networkName {
  227. ipaddr, iperr := UniqueAddress(networkName)
  228. if iperr != nil {
  229. fmt.Println("error in node address assignment!")
  230. return iperr
  231. }
  232. node.Address = ipaddr
  233. node.PullChanges = "yes"
  234. data, err := json.Marshal(&node)
  235. if err != nil {
  236. return err
  237. }
  238. node.SetID()
  239. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  240. }
  241. }
  242. return nil
  243. }
  244. // IsNetworkDisplayNameUnique - checks if displayname is unique from other networks
  245. func IsNetworkDisplayNameUnique(network *models.Network) (bool, error) {
  246. isunique := true
  247. records, err := GetNetworks()
  248. if err != nil && !database.IsEmptyRecord(err) {
  249. return false, err
  250. }
  251. for i := 0; i < len(records); i++ {
  252. if network.NetID == records[i].DisplayName {
  253. isunique = false
  254. }
  255. }
  256. return isunique, nil
  257. }
  258. // IsNetworkNameUnique - checks to see if any other networks have the same name (id)
  259. func IsNetworkNameUnique(network *models.Network) (bool, error) {
  260. isunique := true
  261. dbs, err := GetNetworks()
  262. if err != nil && !database.IsEmptyRecord(err) {
  263. return false, err
  264. }
  265. for i := 0; i < len(dbs); i++ {
  266. if network.NetID == dbs[i].NetID {
  267. isunique = false
  268. }
  269. }
  270. return isunique, nil
  271. }
  272. // UpdateNetwork - updates a network with another network's fields
  273. func UpdateNetwork(currentNetwork *models.Network, newNetwork *models.Network) (bool, bool, error) {
  274. if err := ValidateNetwork(newNetwork, true); err != nil {
  275. return false, false, err
  276. }
  277. if newNetwork.NetID == currentNetwork.NetID {
  278. hasrangeupdate := newNetwork.AddressRange != currentNetwork.AddressRange
  279. localrangeupdate := newNetwork.LocalRange != currentNetwork.LocalRange
  280. data, err := json.Marshal(newNetwork)
  281. if err != nil {
  282. return false, false, err
  283. }
  284. newNetwork.SetNetworkLastModified()
  285. err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME)
  286. return hasrangeupdate, localrangeupdate, err
  287. }
  288. // copy values
  289. return false, false, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.")
  290. }
  291. // Inc - increments an IP
  292. func Inc(ip net.IP) {
  293. for j := len(ip) - 1; j >= 0; j-- {
  294. ip[j]++
  295. if ip[j] > 0 {
  296. break
  297. }
  298. }
  299. }
  300. // GetNetwork - gets a network from database
  301. func GetNetwork(networkname string) (models.Network, error) {
  302. var network models.Network
  303. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
  304. if err != nil {
  305. return network, err
  306. }
  307. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  308. return models.Network{}, err
  309. }
  310. return network, nil
  311. }
  312. // Network.NetIDInNetworkCharSet - checks if a netid of a network uses valid characters
  313. func NetIDInNetworkCharSet(network *models.Network) bool {
  314. charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
  315. for _, char := range network.NetID {
  316. if !strings.Contains(charset, strings.ToLower(string(char))) {
  317. return false
  318. }
  319. }
  320. return true
  321. }
  322. // Network.Validate - validates fields of an network struct
  323. func ValidateNetwork(network *models.Network, isUpdate bool) error {
  324. v := validator.New()
  325. _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
  326. inCharSet := NetIDInNetworkCharSet(network)
  327. if isUpdate {
  328. return inCharSet
  329. }
  330. isFieldUnique, _ := IsNetworkNameUnique(network)
  331. return isFieldUnique && inCharSet
  332. })
  333. //
  334. _ = v.RegisterValidation("displayname_valid", func(fl validator.FieldLevel) bool {
  335. isFieldUnique, _ := IsNetworkDisplayNameUnique(network)
  336. inCharSet := network.DisplayNameInNetworkCharSet()
  337. if isUpdate {
  338. return inCharSet
  339. }
  340. return isFieldUnique && inCharSet
  341. })
  342. _ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
  343. return validation.CheckYesOrNo(fl)
  344. })
  345. err := v.Struct(network)
  346. if err != nil {
  347. for _, e := range err.(validator.ValidationErrors) {
  348. fmt.Println(e)
  349. }
  350. }
  351. return err
  352. }
  353. // == Private ==
  354. func deleteInterface(ifacename string, postdown string) error {
  355. var err error
  356. if !ncutils.IsKernel() {
  357. err = RemoveConf(ifacename, true)
  358. } else {
  359. ipExec, errN := exec.LookPath("ip")
  360. err = errN
  361. if err != nil {
  362. ncutils.PrintLog(err.Error(), 1)
  363. }
  364. _, err = ncutils.RunCmd(ipExec+" link del "+ifacename, false)
  365. if postdown != "" {
  366. runcmds := strings.Split(postdown, "; ")
  367. err = ncutils.RunCmds(runcmds, true)
  368. }
  369. }
  370. return err
  371. }
  372. func isInterfacePresent(iface string, address string) (string, bool) {
  373. var interfaces []net.Interface
  374. var err error
  375. interfaces, err = net.Interfaces()
  376. if err != nil {
  377. Log("ERROR: could not read interfaces", 0)
  378. return "", true
  379. }
  380. for _, currIface := range interfaces {
  381. var currAddrs []net.Addr
  382. currAddrs, err = currIface.Addrs()
  383. if err != nil || len(currAddrs) == 0 {
  384. continue
  385. }
  386. for _, addr := range currAddrs {
  387. if strings.Contains(addr.String(), address) && currIface.Name != iface {
  388. Log("found iface "+addr.String()+" "+currIface.Name, 2)
  389. return currIface.Name, false
  390. }
  391. }
  392. }
  393. Log("failed to find iface "+iface, 2)
  394. return "", true
  395. }