Merge pull request #1926 from gravitl/feature_ingress_refactor

Feature ingress refactor
This commit is contained in:
dcarns 2023-01-13 16:55:29 -05:00 committed by GitHub
commit d38366deb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 97 deletions

View file

@ -339,10 +339,13 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
return
}
host, err := logic.GetHost(node.HostID.String())
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to get ingress gateway host for node [%s] info: %v", nodeid, err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
listenPort := host.LocalListenPort
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to get ingress gateway host for node [%s] info: %v", nodeid, err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
listenPort := host.ListenPort
if host.ProxyEnabled {
listenPort = host.ProxyListenPort
}

View file

@ -923,6 +923,23 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
}
}
}
host, err := logic.GetHost(newNode.HostID.String())
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to get host for node [ %s ] info: %v", nodeid, err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if newNode.IsIngressGateway {
host.ProxyEnabled = true
err := logic.UpsertHost(host)
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to update host [ %s ]: %v", host.ID.String(), err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
}
relayedUpdate := false
if currentNode.IsRelayed && (currentNode.Address.String() != newNode.Address.String() || currentNode.Address6.String() != newNode.Address6.String()) {
relayedUpdate = true

2
go.mod
View file

@ -43,7 +43,7 @@ require (
)
require (
github.com/gravitl/netclient v0.0.0-20230112093844-8ad3677b614d
github.com/gravitl/netclient v0.0.0-20230113135004-f6be74e5e738
github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.0
github.com/olekukonko/tablewriter v0.0.5

4
go.sum
View file

@ -62,8 +62,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gravitl/netclient v0.0.0-20230110162232-fcba83b2f589 h1:3mkVtGOLG0dJxPh2Q0xfJCPPXu3V1qzVqOLE1GhFwKw=
github.com/gravitl/netclient v0.0.0-20230110162232-fcba83b2f589/go.mod h1:8+uvBWa5dn/LgqoeZQvUXd2HESHG05eKywICJs05AgM=
github.com/gravitl/netclient v0.0.0-20230113135004-f6be74e5e738 h1:eKJtQq+dyGDOL59vdd55mm1xovejlW9V4930Lm6lCQQ=
github.com/gravitl/netclient v0.0.0-20230113135004-f6be74e5e738/go.mod h1:g3q+vhLySW/6smOsWsVy5LrxoW++f+kqiBAp9BM6sbY=
github.com/guumaster/tablewriter v0.0.10 h1:A0HD94yMdt4usgxBjoEceNeE0XMJ027euoHAzsPqBQs=
github.com/guumaster/tablewriter v0.0.10/go.mod h1:p4FRFhyfo0UD9ZLmMRbbJooTUsxo6b80qZTERVDWrH8=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=

View file

@ -116,6 +116,7 @@ func GetExtClient(clientid string, network string) (models.ExtClient, error) {
// CreateExtClient - creates an extclient
func CreateExtClient(extclient *models.ExtClient) error {
if extclient.PrivateKey == "" {
privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil {
@ -130,16 +131,15 @@ func CreateExtClient(extclient *models.ExtClient) error {
if err != nil {
return err
}
if extclient.Address == "" {
if parentNetwork.IsIPv4 == "yes" {
newAddress, err := UniqueAddress(extclient.Network, false)
newAddress, err := UniqueAddress(extclient.Network, true)
if err != nil {
return err
}
extclient.Address = newAddress.String()
extclientInternalAddr, err := UniqueAddress(extclient.Network, true)
extclientInternalAddr, err := UniqueAddress(extclient.Network, false)
if err != nil {
return err
}
@ -149,12 +149,12 @@ func CreateExtClient(extclient *models.ExtClient) error {
if extclient.Address6 == "" {
if parentNetwork.IsIPv6 == "yes" {
addr6, err := UniqueAddress6(extclient.Network, false)
addr6, err := UniqueAddress6(extclient.Network, true)
if err != nil {
return err
}
extclient.Address6 = addr6.String()
extclientInternalAddr6, err := UniqueAddress6(extclient.Network, true)
extclientInternalAddr6, err := UniqueAddress6(extclient.Network, false)
if err != nil {
return err
}

View file

@ -211,25 +211,43 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
isunique := true
collection, err := database.FetchRecords(tableName)
if err != nil {
return isunique
}
for _, value := range collection { // filter
var node models.Node
if err = json.Unmarshal([]byte(value), &node); err != nil {
continue
}
if isIpv6 {
if node.Address6.IP.String() == ip && node.Network == network {
return false
if tableName == database.NODES_TABLE_NAME {
var node models.Node
if err = json.Unmarshal([]byte(value), &node); err != nil {
continue
}
} else {
if node.Address.IP.String() == ip && node.Network == network {
return false
if isIpv6 {
if node.Address6.IP.String() == ip && node.Network == network {
return false
}
} else {
if node.Address.IP.String() == ip && node.Network == network {
return false
}
}
} else if tableName == database.EXT_CLIENT_TABLE_NAME {
var extClient models.ExtClient
if err = json.Unmarshal([]byte(value), &extClient); err != nil {
continue
}
if isIpv6 {
if (extClient.Address6 == ip || extClient.InternalIPAddr6 == ip) && extClient.Network == network {
return false
}
} else {
if (extClient.Address == ip || extClient.InternalIPAddr == ip) && extClient.Network == network {
return false
}
}
}
}
return isunique

View file

@ -10,7 +10,6 @@ import (
"strings"
"time"
"github.com/c-robinson/iplib"
proxy_models "github.com/gravitl/netclient/nmproxy/models"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
@ -123,7 +122,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (proxy_models.ProxyMana
logger.Log(1, "failed to resolve udp addr for node: ", peer.ID.String(), host.EndpointIP.String(), err.Error())
continue
}
allowedips := GetAllowedIPs(node, &peer, nil, false)
allowedips := GetAllowedIPs(node, &peer, nil)
var keepalive time.Duration
if node.PersistentKeepalive != 0 {
// set_keepalive
@ -182,7 +181,6 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (proxy_models.ProxyMana
if addr.String() == "" {
addr = node.Address6
}
proxyPayload.WgAddr = addr.String()
proxyPayload.Peers = peers
proxyPayload.PeerMap = peerConfMap
//proxyPayload.Network = node.Network
@ -252,7 +250,7 @@ func GetProxyUpdateForHost(host *models.Host) (proxy_models.ProxyManagerPayload,
proxyPayload.RelayedPeerConf = relayPeersMap
}
var ingressStatus bool
for _, nodeID := range host.Nodes {
node, err := GetNodeByID(nodeID)
@ -288,13 +286,9 @@ func GetProxyUpdateForHost(host *models.Host) (proxy_models.ProxyManagerPayload,
currPeerConf = proxy_models.PeerConf{
Proxy: proxyStatus,
PublicListenPort: int32(listenPort),
NetworkInfo: make(map[string]proxy_models.NetworkInfo),
}
}
currPeerConf.NetworkInfo[peer.Network] = proxy_models.NetworkInfo{
Address: net.ParseIP(peer.PrimaryAddress()),
}
if peerHost.IsRelayed && peerHost.RelayedBy != host.ID.String() {
relayHost, err := GetHost(peerHost.RelayedBy)
@ -316,12 +310,22 @@ func GetProxyUpdateForHost(host *models.Host) (proxy_models.ProxyManagerPayload,
}
}
peerConfMap[peerHost.PublicKey.String()] = currPeerConf
}
}
proxyPayload.PeerMap = peerConfMap
proxyPayload.InterfaceName = models.WIREGUARD_INTERFACE
if node.IsIngressGateway {
ingressStatus = true
_, peerConfMap, err = getExtPeersForProxy(&node, peerConfMap)
if err == nil {
} else if !database.IsEmptyRecord(err) {
logger.Log(1, "error retrieving external clients:", err.Error())
}
}
}
proxyPayload.IsIngress = ingressStatus
proxyPayload.PeerMap = peerConfMap
return proxyPayload, nil
}
@ -410,7 +414,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
if uselocal {
peerConfig.Endpoint.IP = peer.LocalAddress.IP
}
allowedips := getNodeAllowedIPs(&peer, &node)
allowedips := GetAllowedIPs(&node, &peer, nil)
if peer.IsIngressGateway {
for _, entry := range peer.IngressGatewayRange {
_, cidr, err := net.ParseCIDR(string(entry))
@ -450,6 +454,24 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
}
}
if node.IsIngressGateway {
extPeers, extPeerIDAndAddrs, err := getExtPeers(&node, true)
if err == nil {
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID] = make(map[string]models.IDandAddr)
hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID][extPeerIdAndAddr.ID] = models.IDandAddr{
ID: extPeerIdAndAddr.ID,
Address: extPeerIdAndAddr.Address,
Name: extPeerIdAndAddr.Name,
Network: node.Network,
}
}
} else if !database.IsEmptyRecord(err) {
logger.Log(1, "error retrieving external clients:", err.Error())
}
}
}
return hostPeerUpdate, nil
@ -688,14 +710,9 @@ func GetPeerUpdateLegacy(node *models.Node) (models.PeerUpdate, error) {
return models.PeerUpdate{}, err
}
}
fetchRelayedIps := true
if host.ProxyEnabled {
fetchRelayedIps = false
}
allowedips := GetAllowedIPs(node, &peer, metrics, fetchRelayedIps)
allowedips := GetAllowedIPs(node, &peer, metrics)
var keepalive time.Duration
if node.PersistentKeepalive != 0 {
// set_keepalive
keepalive = node.PersistentKeepalive
}
@ -816,6 +833,7 @@ func getExtPeers(node *models.Node, forIngressNode bool) ([]wgtypes.PeerConfig,
peers = append(peers, peer)
idsAndAddr = append(idsAndAddr, models.IDandAddr{
ID: peer.PublicKey.String(),
Name: extPeer.ClientID,
Address: primaryAddr,
})
}
@ -898,7 +916,7 @@ func getExtPeersForProxy(node *models.Node, proxyPeerConf map[string]proxy_model
}
// GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics, fetchRelayedIps bool) []net.IPNet {
func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
var allowedips []net.IPNet
allowedips = getNodeAllowedIPs(peer, node)
@ -933,61 +951,6 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics, fetchRelaye
}
}
}
// handle relay gateway peers
if fetchRelayedIps && peer.IsRelay {
for _, ip := range peer.RelayAddrs {
//find node ID of relayed peer
relayedPeer, err := findNode(ip)
if err != nil {
logger.Log(0, "failed to find node for ip ", ip, err.Error())
continue
}
if relayedPeer == nil {
continue
}
if relayedPeer.ID == node.ID {
//skip self
continue
}
//check if acl permits comms
if !nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(relayedPeer.ID.String())) {
continue
}
if iplib.Version(net.ParseIP(ip)) == 4 {
relayAddr := net.IPNet{
IP: net.ParseIP(ip),
Mask: net.CIDRMask(32, 32),
}
allowedips = append(allowedips, relayAddr)
}
if iplib.Version(net.ParseIP(ip)) == 6 {
relayAddr := net.IPNet{
IP: net.ParseIP(ip),
Mask: net.CIDRMask(128, 128),
}
allowedips = append(allowedips, relayAddr)
}
relayedNode, err := findNode(ip)
if err != nil {
logger.Log(1, "unable to find node for relayed address", ip, err.Error())
continue
}
if relayedNode.IsEgressGateway {
extAllowedIPs := getEgressIPs(node, relayedNode)
allowedips = append(allowedips, extAllowedIPs...)
}
if relayedNode.IsIngressGateway {
extPeers, _, err := getExtPeers(relayedNode, false)
if err == nil {
for _, extPeer := range extPeers {
allowedips = append(allowedips, extPeer.AllowedIPs...)
}
} else {
logger.Log(0, "failed to retrieve extclients from relayed ingress", err.Error())
}
}
}
}
return allowedips
}