gateway.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package logic
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "github.com/gravitl/netmaker/database"
  7. "github.com/gravitl/netmaker/logger"
  8. "github.com/gravitl/netmaker/models"
  9. "github.com/gravitl/netmaker/servercfg"
  10. )
  11. // GetInternetGateways - gets all the nodes that are internet gateways
  12. func GetInternetGateways() ([]models.Node, error) {
  13. nodes, err := GetAllNodes()
  14. if err != nil {
  15. return nil, err
  16. }
  17. igs := make([]models.Node, 0)
  18. for _, node := range nodes {
  19. if !node.IsEgressGateway {
  20. continue
  21. }
  22. for _, ran := range node.EgressGatewayRanges {
  23. if ran == "0.0.0.0/0" {
  24. igs = append(igs, node)
  25. }
  26. }
  27. }
  28. return igs, nil
  29. }
  30. // GetAllIngresses - gets all the nodes that are ingresses
  31. func GetAllIngresses() ([]models.Node, error) {
  32. nodes, err := GetAllNodes()
  33. if err != nil {
  34. return nil, err
  35. }
  36. ingresses := make([]models.Node, 0)
  37. for _, node := range nodes {
  38. if node.IsIngressGateway {
  39. ingresses = append(ingresses, node)
  40. }
  41. }
  42. return ingresses, nil
  43. }
  44. // GetAllEgresses - gets all the nodes that are egresses
  45. func GetAllEgresses() ([]models.Node, error) {
  46. nodes, err := GetAllNodes()
  47. if err != nil {
  48. return nil, err
  49. }
  50. egresses := make([]models.Node, 0)
  51. for _, node := range nodes {
  52. if node.IsEgressGateway {
  53. egresses = append(egresses, node)
  54. }
  55. }
  56. return egresses, nil
  57. }
  58. // CreateEgressGateway - creates an egress gateway
  59. func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, error) {
  60. node, err := GetNodeByID(gateway.NodeID)
  61. if err != nil {
  62. return models.Node{}, err
  63. }
  64. host, err := GetHost(node.HostID.String())
  65. if err != nil {
  66. return models.Node{}, err
  67. }
  68. if host.OS != "linux" { // support for other OS to be added
  69. return models.Node{}, errors.New(host.OS + " is unsupported for egress gateways")
  70. }
  71. if host.FirewallInUse == models.FIREWALL_NONE {
  72. return models.Node{}, errors.New("firewall is not supported for egress gateways")
  73. }
  74. for i := len(gateway.Ranges) - 1; i >= 0; i-- {
  75. // check if internet gateway IPv4
  76. if gateway.Ranges[i] == "0.0.0.0/0" && FreeTier {
  77. return models.Node{}, fmt.Errorf("currently IPv4 internet gateways are not supported on the free tier: %s", gateway.Ranges[i])
  78. }
  79. // check if internet gateway IPv6
  80. if gateway.Ranges[i] == "::/0" {
  81. return models.Node{}, fmt.Errorf("currently IPv6 internet gateways are not supported: %s", gateway.Ranges[i])
  82. }
  83. normalized, err := NormalizeCIDR(gateway.Ranges[i])
  84. if err != nil {
  85. return models.Node{}, err
  86. }
  87. gateway.Ranges[i] = normalized
  88. }
  89. if gateway.NatEnabled == "" {
  90. gateway.NatEnabled = "yes"
  91. }
  92. err = ValidateEgressGateway(gateway)
  93. if err != nil {
  94. return models.Node{}, err
  95. }
  96. node.IsEgressGateway = true
  97. node.EgressGatewayRanges = gateway.Ranges
  98. node.EgressGatewayNatEnabled = models.ParseBool(gateway.NatEnabled)
  99. node.EgressGatewayRequest = gateway // store entire request for use when preserving the egress gateway
  100. node.SetLastModified()
  101. if err = UpsertNode(&node); err != nil {
  102. return models.Node{}, err
  103. }
  104. return node, nil
  105. }
  106. // ValidateEgressGateway - validates the egress gateway model
  107. func ValidateEgressGateway(gateway models.EgressGatewayRequest) error {
  108. var err error
  109. empty := len(gateway.Ranges) == 0
  110. if empty {
  111. err = errors.New("IP Ranges Cannot Be Empty")
  112. }
  113. return err
  114. }
  115. // DeleteEgressGateway - deletes egress from node
  116. func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
  117. node, err := GetNodeByID(nodeid)
  118. if err != nil {
  119. return models.Node{}, err
  120. }
  121. node.IsEgressGateway = false
  122. node.EgressGatewayRanges = []string{}
  123. node.EgressGatewayRequest = models.EgressGatewayRequest{} // remove preserved request as the egress gateway is gone
  124. node.SetLastModified()
  125. if err = UpsertNode(&node); err != nil {
  126. return models.Node{}, err
  127. }
  128. return node, nil
  129. }
  130. // CreateIngressGateway - creates an ingress gateway
  131. func CreateIngressGateway(netid string, nodeid string, ingress models.IngressRequest) (models.Node, error) {
  132. node, err := GetNodeByID(nodeid)
  133. if err != nil {
  134. return models.Node{}, err
  135. }
  136. if node.IsRelayed {
  137. return models.Node{}, errors.New("ingress cannot be created on a relayed node")
  138. }
  139. host, err := GetHost(node.HostID.String())
  140. if err != nil {
  141. return models.Node{}, err
  142. }
  143. if host.OS != "linux" {
  144. return models.Node{}, errors.New("ingress can only be created on linux based node")
  145. }
  146. if host.FirewallInUse == models.FIREWALL_NONE {
  147. return models.Node{}, errors.New("firewall is not supported for ingress gateways")
  148. }
  149. network, err := GetParentNetwork(netid)
  150. if err != nil {
  151. return models.Node{}, err
  152. }
  153. node.IsIngressGateway = true
  154. node.IngressGatewayRange = network.AddressRange
  155. node.IngressGatewayRange6 = network.AddressRange6
  156. node.IngressDNS = ingress.ExtclientDNS
  157. node.SetLastModified()
  158. if ingress.Failover && servercfg.IsPro {
  159. node.Failover = true
  160. }
  161. err = UpsertNode(&node)
  162. if err != nil {
  163. return models.Node{}, err
  164. }
  165. err = SetNetworkNodesLastModified(netid)
  166. return node, err
  167. }
  168. // GetIngressGwUsers - lists the users having to access to ingressGW
  169. func GetIngressGwUsers(node models.Node) (models.IngressGwUsers, error) {
  170. gwUsers := models.IngressGwUsers{
  171. NodeID: node.ID.String(),
  172. Network: node.Network,
  173. }
  174. users, err := GetUsers()
  175. if err != nil {
  176. return gwUsers, err
  177. }
  178. for _, user := range users {
  179. if !user.IsAdmin && !user.IsSuperAdmin {
  180. gwUsers.Users = append(gwUsers.Users, user)
  181. }
  182. }
  183. return gwUsers, nil
  184. }
  185. // DeleteIngressGateway - deletes an ingress gateway
  186. func DeleteIngressGateway(nodeid string) (models.Node, bool, []models.ExtClient, error) {
  187. removedClients := []models.ExtClient{}
  188. node, err := GetNodeByID(nodeid)
  189. if err != nil {
  190. return models.Node{}, false, removedClients, err
  191. }
  192. clients, err := GetExtClientsByID(nodeid, node.Network)
  193. if err != nil && !database.IsEmptyRecord(err) {
  194. return models.Node{}, false, removedClients, err
  195. }
  196. removedClients = clients
  197. // delete ext clients belonging to ingress gateway
  198. if err = DeleteGatewayExtClients(node.ID.String(), node.Network); err != nil {
  199. return models.Node{}, false, removedClients, err
  200. }
  201. logger.Log(3, "deleting ingress gateway")
  202. wasFailover := node.Failover
  203. node.LastModified = time.Now()
  204. node.IsIngressGateway = false
  205. node.IngressGatewayRange = ""
  206. node.Failover = false
  207. err = UpsertNode(&node)
  208. if err != nil {
  209. return models.Node{}, wasFailover, removedClients, err
  210. }
  211. err = SetNetworkNodesLastModified(node.Network)
  212. return node, wasFailover, removedClients, err
  213. }
  214. // DeleteGatewayExtClients - deletes ext clients based on gateway (mac) of ingress node and network
  215. func DeleteGatewayExtClients(gatewayID string, networkName string) error {
  216. currentExtClients, err := GetNetworkExtClients(networkName)
  217. if database.IsEmptyRecord(err) {
  218. return nil
  219. }
  220. if err != nil {
  221. return err
  222. }
  223. for _, extClient := range currentExtClients {
  224. if extClient.IngressGatewayID == gatewayID {
  225. if err = DeleteExtClient(networkName, extClient.ClientID); err != nil {
  226. logger.Log(1, "failed to remove ext client", extClient.ClientID)
  227. continue
  228. }
  229. }
  230. }
  231. return nil
  232. }
  233. // IsUserAllowedAccessToExtClient - checks if user has permission to access extclient
  234. func IsUserAllowedAccessToExtClient(username string, client models.ExtClient) bool {
  235. if username == MasterUser {
  236. return true
  237. }
  238. user, err := GetUser(username)
  239. if err != nil {
  240. return false
  241. }
  242. if !user.IsAdmin && !user.IsSuperAdmin {
  243. if user.UserName != client.OwnerID {
  244. return false
  245. }
  246. }
  247. return true
  248. }