mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-12 08:04:25 +08:00
NET-710: Internet Gws Re-Design (#2718)
* add internet gateway to client gateway * migration func to remove internet egress range from egress gateway * add internet gateways ranges to firewall update * add internet gw ranges to extcleint conf * add ipv6 internet address * remove failover field from ingress req * only let normal to be created on PRO (#2716) * feat(NET-805): send internet gw props to rac * set inet gw field on node update api * move internet gws to EE --------- Co-authored-by: the_aceix <aceixsmartx@gmail.com>
This commit is contained in:
parent
03db704436
commit
530dbdc65c
10 changed files with 150 additions and 57 deletions
|
@ -216,7 +216,15 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
||||||
} else {
|
} else {
|
||||||
gwendpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), host.ListenPort)
|
gwendpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), host.ListenPort)
|
||||||
}
|
}
|
||||||
newAllowedIPs := network.AddressRange
|
var newAllowedIPs string
|
||||||
|
if logic.IsInternetGw(gwnode) {
|
||||||
|
egressrange := "0.0.0.0/0"
|
||||||
|
if gwnode.Address6.IP != nil && client.Address6 != "" {
|
||||||
|
egressrange += "," + "::/0"
|
||||||
|
}
|
||||||
|
newAllowedIPs = egressrange
|
||||||
|
} else {
|
||||||
|
newAllowedIPs = network.AddressRange
|
||||||
if newAllowedIPs != "" && network.AddressRange6 != "" {
|
if newAllowedIPs != "" && network.AddressRange6 != "" {
|
||||||
newAllowedIPs += ","
|
newAllowedIPs += ","
|
||||||
}
|
}
|
||||||
|
@ -228,6 +236,8 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
||||||
newAllowedIPs += "," + egressGatewayRange
|
newAllowedIPs += "," + egressGatewayRange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defaultDNS := ""
|
defaultDNS := ""
|
||||||
if client.DNS != "" {
|
if client.DNS != "" {
|
||||||
defaultDNS = "DNS = " + client.DNS
|
defaultDNS = "DNS = " + client.DNS
|
||||||
|
|
|
@ -10,6 +10,16 @@ import (
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// SetInternetGw - sets the node as internet gw based on flag bool
|
||||||
|
SetInternetGw = func(node *models.Node, flag bool) {
|
||||||
|
}
|
||||||
|
// IsInternetGw - checks if node is acting as internet gw
|
||||||
|
IsInternetGw = func(node models.Node) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// GetInternetGateways - gets all the nodes that are internet gateways
|
// GetInternetGateways - gets all the nodes that are internet gateways
|
||||||
func GetInternetGateways() ([]models.Node, error) {
|
func GetInternetGateways() ([]models.Node, error) {
|
||||||
nodes, err := GetAllNodes()
|
nodes, err := GetAllNodes()
|
||||||
|
@ -78,12 +88,8 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
|
||||||
}
|
}
|
||||||
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
||||||
// check if internet gateway IPv4
|
// check if internet gateway IPv4
|
||||||
if gateway.Ranges[i] == "0.0.0.0/0" && FreeTier {
|
if gateway.Ranges[i] == "0.0.0.0/0" || gateway.Ranges[i] == "::/0" {
|
||||||
return models.Node{}, fmt.Errorf("currently IPv4 internet gateways are not supported on the free tier: %s", gateway.Ranges[i])
|
return models.Node{}, fmt.Errorf("create internet gateways on the remote client gateway")
|
||||||
}
|
|
||||||
// check if internet gateway IPv6
|
|
||||||
if gateway.Ranges[i] == "::/0" {
|
|
||||||
return models.Node{}, fmt.Errorf("currently IPv6 internet gateways are not supported: %s", gateway.Ranges[i])
|
|
||||||
}
|
}
|
||||||
normalized, err := NormalizeCIDR(gateway.Ranges[i])
|
normalized, err := NormalizeCIDR(gateway.Ranges[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -163,6 +169,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
|
||||||
return models.Node{}, err
|
return models.Node{}, err
|
||||||
}
|
}
|
||||||
node.IsIngressGateway = true
|
node.IsIngressGateway = true
|
||||||
|
SetInternetGw(&node, ingress.IsInternetGateway)
|
||||||
node.IngressGatewayRange = network.AddressRange
|
node.IngressGatewayRange = network.AddressRange
|
||||||
node.IngressGatewayRange6 = network.AddressRange6
|
node.IngressGatewayRange6 = network.AddressRange6
|
||||||
node.IngressDNS = ingress.ExtclientDNS
|
node.IngressDNS = ingress.ExtclientDNS
|
||||||
|
@ -215,6 +222,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
|
||||||
logger.Log(3, "deleting ingress gateway")
|
logger.Log(3, "deleting ingress gateway")
|
||||||
node.LastModified = time.Now()
|
node.LastModified = time.Now()
|
||||||
node.IsIngressGateway = false
|
node.IsIngressGateway = false
|
||||||
|
node.IsInternetGateway = false
|
||||||
node.IngressGatewayRange = ""
|
node.IngressGatewayRange = ""
|
||||||
err = UpsertNode(&node)
|
err = UpsertNode(&node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -241,8 +241,18 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||||
logger.Log(1, "error retrieving external clients:", err.Error())
|
logger.Log(1, "error retrieving external clients:", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addedInetGwRanges := false
|
||||||
if node.IsEgressGateway && node.EgressGatewayRequest.NatEnabled == "yes" && len(node.EgressGatewayRequest.Ranges) > 0 {
|
if node.IsEgressGateway && node.EgressGatewayRequest.NatEnabled == "yes" && len(node.EgressGatewayRequest.Ranges) > 0 {
|
||||||
hostPeerUpdate.FwUpdate.IsEgressGw = true
|
hostPeerUpdate.FwUpdate.IsEgressGw = true
|
||||||
|
if IsInternetGw(node) {
|
||||||
|
hostPeerUpdate.FwUpdate.IsEgressGw = true
|
||||||
|
egressrange := []string{"0.0.0.0/0"}
|
||||||
|
if node.Address6.IP != nil {
|
||||||
|
egressrange = append(egressrange, "::/0")
|
||||||
|
}
|
||||||
|
node.EgressGatewayRequest.Ranges = append(node.EgressGatewayRequest.Ranges, egressrange...)
|
||||||
|
addedInetGwRanges = true
|
||||||
|
}
|
||||||
hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
||||||
EgressID: node.ID.String(),
|
EgressID: node.ID.String(),
|
||||||
Network: node.PrimaryNetworkRange(),
|
Network: node.PrimaryNetworkRange(),
|
||||||
|
@ -252,6 +262,28 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||||
},
|
},
|
||||||
EgressGWCfg: node.EgressGatewayRequest,
|
EgressGWCfg: node.EgressGatewayRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if IsInternetGw(node) && !addedInetGwRanges {
|
||||||
|
hostPeerUpdate.FwUpdate.IsEgressGw = true
|
||||||
|
egressrange := []string{"0.0.0.0/0"}
|
||||||
|
if node.Address6.IP != nil {
|
||||||
|
egressrange = append(egressrange, "::/0")
|
||||||
|
}
|
||||||
|
hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
||||||
|
EgressID: node.ID.String(),
|
||||||
|
Network: node.PrimaryAddressIPNet(),
|
||||||
|
EgressGwAddr: net.IPNet{
|
||||||
|
IP: net.ParseIP(node.PrimaryAddress()),
|
||||||
|
Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
|
||||||
|
},
|
||||||
|
EgressGWCfg: models.EgressGatewayRequest{
|
||||||
|
NodeID: node.ID.String(),
|
||||||
|
NetID: node.Network,
|
||||||
|
NatEnabled: "yes",
|
||||||
|
Ranges: egressrange,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// == post peer calculations ==
|
// == post peer calculations ==
|
||||||
|
|
|
@ -18,6 +18,7 @@ func Run() {
|
||||||
updateEnrollmentKeys()
|
updateEnrollmentKeys()
|
||||||
assignSuperAdmin()
|
assignSuperAdmin()
|
||||||
updateHosts()
|
updateHosts()
|
||||||
|
updateNodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func assignSuperAdmin() {
|
func assignSuperAdmin() {
|
||||||
|
@ -137,3 +138,32 @@ func updateHosts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateNodes() {
|
||||||
|
nodes, err := logic.GetAllNodes()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("migration failed for nodes", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.IsEgressGateway {
|
||||||
|
egressRanges, update := removeInterGw(node.EgressGatewayRanges)
|
||||||
|
if update {
|
||||||
|
node.EgressGatewayRequest.Ranges = egressRanges
|
||||||
|
node.EgressGatewayRanges = egressRanges
|
||||||
|
logic.UpsertNode(&node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeInterGw(egressRanges []string) ([]string, bool) {
|
||||||
|
update := false
|
||||||
|
for i := len(egressRanges) - 1; i >= 0; i-- {
|
||||||
|
if egressRanges[i] == "0.0.0.0/0" || egressRanges[i] == "::/0" {
|
||||||
|
update = true
|
||||||
|
egressRanges = append(egressRanges[:i], egressRanges[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return egressRanges, update
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ type ApiNode struct {
|
||||||
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
||||||
IsEgressGateway bool `json:"isegressgateway"`
|
IsEgressGateway bool `json:"isegressgateway"`
|
||||||
IsIngressGateway bool `json:"isingressgateway"`
|
IsIngressGateway bool `json:"isingressgateway"`
|
||||||
|
IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
|
||||||
EgressGatewayRanges []string `json:"egressgatewayranges"`
|
EgressGatewayRanges []string `json:"egressgatewayranges"`
|
||||||
EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled"`
|
EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled"`
|
||||||
DNSOn bool `json:"dnson"`
|
DNSOn bool `json:"dnson"`
|
||||||
|
@ -67,6 +68,7 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
||||||
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
|
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
|
||||||
convertedNode.DNSOn = a.DNSOn
|
convertedNode.DNSOn = a.DNSOn
|
||||||
convertedNode.IngressDNS = a.IngressDns
|
convertedNode.IngressDNS = a.IngressDns
|
||||||
|
convertedNode.IsInternetGateway = a.IsInternetGateway
|
||||||
convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest
|
convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest
|
||||||
convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled
|
convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled
|
||||||
convertedNode.RelayedNodes = a.RelayedNodes
|
convertedNode.RelayedNodes = a.RelayedNodes
|
||||||
|
@ -88,10 +90,6 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
||||||
} else if !isEmptyAddr(currentNode.LocalAddress.String()) {
|
} else if !isEmptyAddr(currentNode.LocalAddress.String()) {
|
||||||
convertedNode.LocalAddress = currentNode.LocalAddress
|
convertedNode.LocalAddress = currentNode.LocalAddress
|
||||||
}
|
}
|
||||||
udpAddr, err := net.ResolveUDPAddr("udp", a.InternetGateway)
|
|
||||||
if err == nil {
|
|
||||||
convertedNode.InternetGateway = udpAddr
|
|
||||||
}
|
|
||||||
ip, addr, err := net.ParseCIDR(a.Address)
|
ip, addr, err := net.ParseCIDR(a.Address)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
convertedNode.Address = *addr
|
convertedNode.Address = *addr
|
||||||
|
@ -150,13 +148,13 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
|
||||||
apiNode.DNSOn = nm.DNSOn
|
apiNode.DNSOn = nm.DNSOn
|
||||||
apiNode.IngressDns = nm.IngressDNS
|
apiNode.IngressDns = nm.IngressDNS
|
||||||
apiNode.Server = nm.Server
|
apiNode.Server = nm.Server
|
||||||
apiNode.InternetGateway = nm.InternetGateway.String()
|
|
||||||
if isEmptyAddr(apiNode.InternetGateway) {
|
if isEmptyAddr(apiNode.InternetGateway) {
|
||||||
apiNode.InternetGateway = ""
|
apiNode.InternetGateway = ""
|
||||||
}
|
}
|
||||||
apiNode.Connected = nm.Connected
|
apiNode.Connected = nm.Connected
|
||||||
apiNode.PendingDelete = nm.PendingDelete
|
apiNode.PendingDelete = nm.PendingDelete
|
||||||
apiNode.DefaultACL = nm.DefaultACL
|
apiNode.DefaultACL = nm.DefaultACL
|
||||||
|
apiNode.IsInternetGateway = nm.IsInternetGateway
|
||||||
apiNode.IsFailOver = nm.IsFailOver
|
apiNode.IsFailOver = nm.IsFailOver
|
||||||
apiNode.FailOverPeers = nm.FailOverPeers
|
apiNode.FailOverPeers = nm.FailOverPeers
|
||||||
apiNode.FailedOverBy = nm.FailedOverBy
|
apiNode.FailedOverBy = nm.FailedOverBy
|
||||||
|
|
|
@ -59,7 +59,6 @@ type CommonNode struct {
|
||||||
Network string `json:"network" yaml:"network"`
|
Network string `json:"network" yaml:"network"`
|
||||||
NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"`
|
NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"`
|
||||||
NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"`
|
NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"`
|
||||||
InternetGateway *net.UDPAddr `json:"internetgateway" yaml:"internetgateway"`
|
|
||||||
Server string `json:"server" yaml:"server"`
|
Server string `json:"server" yaml:"server"`
|
||||||
Connected bool `json:"connected" yaml:"connected"`
|
Connected bool `json:"connected" yaml:"connected"`
|
||||||
Address net.IPNet `json:"address" yaml:"address"`
|
Address net.IPNet `json:"address" yaml:"address"`
|
||||||
|
@ -69,6 +68,7 @@ type CommonNode struct {
|
||||||
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
||||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||||
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
||||||
|
IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
|
||||||
IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
|
IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
|
||||||
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
|
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
|
||||||
IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"`
|
IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"`
|
||||||
|
|
|
@ -68,6 +68,7 @@ type UserRemoteGws struct {
|
||||||
GWName string `json:"gw_name"`
|
GWName string `json:"gw_name"`
|
||||||
Network string `json:"network"`
|
Network string `json:"network"`
|
||||||
Connected bool `json:"connected"`
|
Connected bool `json:"connected"`
|
||||||
|
IsInternetGateway bool `json:"is_internet_gateway"`
|
||||||
GwClient ExtClient `json:"gw_client"`
|
GwClient ExtClient `json:"gw_client"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ type HostRelayRequest struct {
|
||||||
// IngressRequest - ingress request struct
|
// IngressRequest - ingress request struct
|
||||||
type IngressRequest struct {
|
type IngressRequest struct {
|
||||||
ExtclientDNS string `json:"extclientdns"`
|
ExtclientDNS string `json:"extclientdns"`
|
||||||
Failover bool `json:"failover"`
|
IsInternetGateway bool `json:"is_internet_gw"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerUpdateData - contains data to configure server
|
// ServerUpdateData - contains data to configure server
|
||||||
|
|
|
@ -202,6 +202,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
|
||||||
Network: node.Network,
|
Network: node.Network,
|
||||||
GwClient: extClient,
|
GwClient: extClient,
|
||||||
Connected: true,
|
Connected: true,
|
||||||
|
IsInternetGateway: node.IsInternetGateway,
|
||||||
})
|
})
|
||||||
userGws[node.Network] = gws
|
userGws[node.Network] = gws
|
||||||
delete(user.RemoteGwIDs, node.ID.String())
|
delete(user.RemoteGwIDs, node.ID.String())
|
||||||
|
@ -233,6 +234,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
|
||||||
GwID: node.ID.String(),
|
GwID: node.ID.String(),
|
||||||
GWName: host.Name,
|
GWName: host.Name,
|
||||||
Network: node.Network,
|
Network: node.Network,
|
||||||
|
IsInternetGateway: node.IsInternetGateway,
|
||||||
})
|
})
|
||||||
userGws[node.Network] = gws
|
userGws[node.Network] = gws
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@ func InitPro() {
|
||||||
logic.UpdateRelayed = proLogic.UpdateRelayed
|
logic.UpdateRelayed = proLogic.UpdateRelayed
|
||||||
logic.SetRelayedNodes = proLogic.SetRelayedNodes
|
logic.SetRelayedNodes = proLogic.SetRelayedNodes
|
||||||
logic.RelayUpdates = proLogic.RelayUpdates
|
logic.RelayUpdates = proLogic.RelayUpdates
|
||||||
|
logic.IsInternetGw = proLogic.IsInternetGw
|
||||||
|
logic.SetInternetGw = proLogic.SetInternetGw
|
||||||
mq.UpdateMetrics = proLogic.MQUpdateMetrics
|
mq.UpdateMetrics = proLogic.MQUpdateMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,16 @@ import (
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// IsInternetGw - checks if node is acting as internet gw
|
||||||
|
func IsInternetGw(node models.Node) bool {
|
||||||
|
return node.IsInternetGateway
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetInternetGw - sets the node as internet gw based on flag bool
|
||||||
|
func SetInternetGw(node *models.Node, flag bool) {
|
||||||
|
node.IsInternetGateway = flag
|
||||||
|
}
|
||||||
|
|
||||||
// GetNetworkIngresses - gets the gateways of a network
|
// GetNetworkIngresses - gets the gateways of a network
|
||||||
func GetNetworkIngresses(network string) ([]models.Node, error) {
|
func GetNetworkIngresses(network string) ([]models.Node, error) {
|
||||||
var ingresses []models.Node
|
var ingresses []models.Node
|
||||||
|
|
Loading…
Add table
Reference in a new issue