mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-05 20:54:18 +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,18 +216,28 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
|||
} else {
|
||||
gwendpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), host.ListenPort)
|
||||
}
|
||||
newAllowedIPs := network.AddressRange
|
||||
if newAllowedIPs != "" && network.AddressRange6 != "" {
|
||||
newAllowedIPs += ","
|
||||
}
|
||||
if network.AddressRange6 != "" {
|
||||
newAllowedIPs += network.AddressRange6
|
||||
}
|
||||
if egressGatewayRanges, err := logic.GetEgressRangesOnNetwork(&client); err == nil {
|
||||
for _, egressGatewayRange := range egressGatewayRanges {
|
||||
newAllowedIPs += "," + egressGatewayRange
|
||||
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 != "" {
|
||||
newAllowedIPs += ","
|
||||
}
|
||||
if network.AddressRange6 != "" {
|
||||
newAllowedIPs += network.AddressRange6
|
||||
}
|
||||
if egressGatewayRanges, err := logic.GetEgressRangesOnNetwork(&client); err == nil {
|
||||
for _, egressGatewayRange := range egressGatewayRanges {
|
||||
newAllowedIPs += "," + egressGatewayRange
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultDNS := ""
|
||||
if client.DNS != "" {
|
||||
defaultDNS = "DNS = " + client.DNS
|
||||
|
|
|
@ -10,6 +10,16 @@ import (
|
|||
"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
|
||||
func GetInternetGateways() ([]models.Node, error) {
|
||||
nodes, err := GetAllNodes()
|
||||
|
@ -78,12 +88,8 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
|
|||
}
|
||||
for i := len(gateway.Ranges) - 1; i >= 0; i-- {
|
||||
// check if internet gateway IPv4
|
||||
if gateway.Ranges[i] == "0.0.0.0/0" && FreeTier {
|
||||
return models.Node{}, fmt.Errorf("currently IPv4 internet gateways are not supported on the free tier: %s", gateway.Ranges[i])
|
||||
}
|
||||
// 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])
|
||||
if gateway.Ranges[i] == "0.0.0.0/0" || gateway.Ranges[i] == "::/0" {
|
||||
return models.Node{}, fmt.Errorf("create internet gateways on the remote client gateway")
|
||||
}
|
||||
normalized, err := NormalizeCIDR(gateway.Ranges[i])
|
||||
if err != nil {
|
||||
|
@ -163,6 +169,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
|
|||
return models.Node{}, err
|
||||
}
|
||||
node.IsIngressGateway = true
|
||||
SetInternetGw(&node, ingress.IsInternetGateway)
|
||||
node.IngressGatewayRange = network.AddressRange
|
||||
node.IngressGatewayRange6 = network.AddressRange6
|
||||
node.IngressDNS = ingress.ExtclientDNS
|
||||
|
@ -215,6 +222,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
|
|||
logger.Log(3, "deleting ingress gateway")
|
||||
node.LastModified = time.Now()
|
||||
node.IsIngressGateway = false
|
||||
node.IsInternetGateway = false
|
||||
node.IngressGatewayRange = ""
|
||||
err = UpsertNode(&node)
|
||||
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())
|
||||
}
|
||||
}
|
||||
addedInetGwRanges := false
|
||||
if node.IsEgressGateway && node.EgressGatewayRequest.NatEnabled == "yes" && len(node.EgressGatewayRequest.Ranges) > 0 {
|
||||
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{
|
||||
EgressID: node.ID.String(),
|
||||
Network: node.PrimaryNetworkRange(),
|
||||
|
@ -252,6 +262,28 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
},
|
||||
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 ==
|
||||
|
|
|
@ -18,6 +18,7 @@ func Run() {
|
|||
updateEnrollmentKeys()
|
||||
assignSuperAdmin()
|
||||
updateHosts()
|
||||
updateNodes()
|
||||
}
|
||||
|
||||
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"`
|
||||
IsEgressGateway bool `json:"isegressgateway"`
|
||||
IsIngressGateway bool `json:"isingressgateway"`
|
||||
IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges"`
|
||||
EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled"`
|
||||
DNSOn bool `json:"dnson"`
|
||||
|
@ -67,6 +68,7 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
|||
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
|
||||
convertedNode.DNSOn = a.DNSOn
|
||||
convertedNode.IngressDNS = a.IngressDns
|
||||
convertedNode.IsInternetGateway = a.IsInternetGateway
|
||||
convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest
|
||||
convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled
|
||||
convertedNode.RelayedNodes = a.RelayedNodes
|
||||
|
@ -88,10 +90,6 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
|||
} else if !isEmptyAddr(currentNode.LocalAddress.String()) {
|
||||
convertedNode.LocalAddress = currentNode.LocalAddress
|
||||
}
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", a.InternetGateway)
|
||||
if err == nil {
|
||||
convertedNode.InternetGateway = udpAddr
|
||||
}
|
||||
ip, addr, err := net.ParseCIDR(a.Address)
|
||||
if err == nil {
|
||||
convertedNode.Address = *addr
|
||||
|
@ -150,13 +148,13 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
|
|||
apiNode.DNSOn = nm.DNSOn
|
||||
apiNode.IngressDns = nm.IngressDNS
|
||||
apiNode.Server = nm.Server
|
||||
apiNode.InternetGateway = nm.InternetGateway.String()
|
||||
if isEmptyAddr(apiNode.InternetGateway) {
|
||||
apiNode.InternetGateway = ""
|
||||
}
|
||||
apiNode.Connected = nm.Connected
|
||||
apiNode.PendingDelete = nm.PendingDelete
|
||||
apiNode.DefaultACL = nm.DefaultACL
|
||||
apiNode.IsInternetGateway = nm.IsInternetGateway
|
||||
apiNode.IsFailOver = nm.IsFailOver
|
||||
apiNode.FailOverPeers = nm.FailOverPeers
|
||||
apiNode.FailedOverBy = nm.FailedOverBy
|
||||
|
|
|
@ -54,27 +54,27 @@ type Iface struct {
|
|||
|
||||
// CommonNode - represents a commonn node data elements shared by netmaker and netclient
|
||||
type CommonNode struct {
|
||||
ID uuid.UUID `json:"id" yaml:"id"`
|
||||
HostID uuid.UUID `json:"hostid" yaml:"hostid"`
|
||||
Network string `json:"network" yaml:"network"`
|
||||
NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"`
|
||||
NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"`
|
||||
InternetGateway *net.UDPAddr `json:"internetgateway" yaml:"internetgateway"`
|
||||
Server string `json:"server" yaml:"server"`
|
||||
Connected bool `json:"connected" yaml:"connected"`
|
||||
Address net.IPNet `json:"address" yaml:"address"`
|
||||
Address6 net.IPNet `json:"address6" yaml:"address6"`
|
||||
Action string `json:"action" yaml:"action"`
|
||||
LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"`
|
||||
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
||||
IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
|
||||
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
|
||||
IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"`
|
||||
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
||||
IngressDNS string `json:"ingressdns" yaml:"ingressdns"`
|
||||
DNSOn bool `json:"dnson" yaml:"dnson"`
|
||||
ID uuid.UUID `json:"id" yaml:"id"`
|
||||
HostID uuid.UUID `json:"hostid" yaml:"hostid"`
|
||||
Network string `json:"network" yaml:"network"`
|
||||
NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"`
|
||||
NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"`
|
||||
Server string `json:"server" yaml:"server"`
|
||||
Connected bool `json:"connected" yaml:"connected"`
|
||||
Address net.IPNet `json:"address" yaml:"address"`
|
||||
Address6 net.IPNet `json:"address6" yaml:"address6"`
|
||||
Action string `json:"action" yaml:"action"`
|
||||
LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"`
|
||||
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
||||
IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
|
||||
IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
|
||||
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
|
||||
IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"`
|
||||
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
||||
IngressDNS string `json:"ingressdns" yaml:"ingressdns"`
|
||||
DNSOn bool `json:"dnson" yaml:"dnson"`
|
||||
}
|
||||
|
||||
// Node - a model of a network node
|
||||
|
|
|
@ -64,11 +64,12 @@ type IngressGwUsers struct {
|
|||
|
||||
// UserRemoteGws - struct to hold user's remote gws
|
||||
type UserRemoteGws struct {
|
||||
GwID string `json:"remote_access_gw_id"`
|
||||
GWName string `json:"gw_name"`
|
||||
Network string `json:"network"`
|
||||
Connected bool `json:"connected"`
|
||||
GwClient ExtClient `json:"gw_client"`
|
||||
GwID string `json:"remote_access_gw_id"`
|
||||
GWName string `json:"gw_name"`
|
||||
Network string `json:"network"`
|
||||
Connected bool `json:"connected"`
|
||||
IsInternetGateway bool `json:"is_internet_gateway"`
|
||||
GwClient ExtClient `json:"gw_client"`
|
||||
}
|
||||
|
||||
// UserRemoteGwsReq - struct to hold user remote acccess gws req
|
||||
|
@ -189,8 +190,8 @@ type HostRelayRequest struct {
|
|||
|
||||
// IngressRequest - ingress request struct
|
||||
type IngressRequest struct {
|
||||
ExtclientDNS string `json:"extclientdns"`
|
||||
Failover bool `json:"failover"`
|
||||
ExtclientDNS string `json:"extclientdns"`
|
||||
IsInternetGateway bool `json:"is_internet_gw"`
|
||||
}
|
||||
|
||||
// ServerUpdateData - contains data to configure server
|
||||
|
|
|
@ -197,11 +197,12 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
|
|||
gws := userGws[node.Network]
|
||||
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
GwClient: extClient,
|
||||
Connected: true,
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
GwClient: extClient,
|
||||
Connected: true,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
delete(user.RemoteGwIDs, node.ID.String())
|
||||
|
@ -230,9 +231,10 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
|
|||
gws := userGws[node.Network]
|
||||
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ func InitPro() {
|
|||
logic.UpdateRelayed = proLogic.UpdateRelayed
|
||||
logic.SetRelayedNodes = proLogic.SetRelayedNodes
|
||||
logic.RelayUpdates = proLogic.RelayUpdates
|
||||
logic.IsInternetGw = proLogic.IsInternetGw
|
||||
logic.SetInternetGw = proLogic.SetInternetGw
|
||||
mq.UpdateMetrics = proLogic.MQUpdateMetrics
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,16 @@ import (
|
|||
"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
|
||||
func GetNetworkIngresses(network string) ([]models.Node, error) {
|
||||
var ingresses []models.Node
|
||||
|
|
Loading…
Add table
Reference in a new issue