add egress gw info to host update

This commit is contained in:
Abhishek Kondur 2023-02-02 10:22:20 +04:00
parent fba6940426
commit 04ac036b68
3 changed files with 55 additions and 43 deletions

View file

@ -687,33 +687,32 @@ func createNode(w http.ResponseWriter, r *http.Request) {
// Responses:
// 200: nodeResponse
func createEgressGateway(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("currently unimplemented"), "internal"))
// var gateway models.EgressGatewayRequest
// var params = mux.Vars(r)
// w.Header().Set("Content-Type", "application/json")
// err := json.NewDecoder(r.Body).Decode(&gateway)
// if err != nil {
// logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
// logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
// return
// }
// gateway.NetID = params["network"]
// gateway.NodeID = params["nodeid"]
// node, err := logic.CreateEgressGateway(gateway)
// if err != nil {
// logger.Log(0, r.Header.Get("user"),
// fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
// gateway.NodeID, gateway.NetID, err))
// logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
// return
// }
//
// apiNode := node.ConvertToAPINode()
// logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
// w.WriteHeader(http.StatusOK)
// json.NewEncoder(w).Encode(apiNode)
//
// runUpdates(&node, true)
var gateway models.EgressGatewayRequest
var params = mux.Vars(r)
w.Header().Set("Content-Type", "application/json")
err := json.NewDecoder(r.Body).Decode(&gateway)
if err != nil {
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
gateway.NetID = params["network"]
gateway.NodeID = params["nodeid"]
node, err := logic.CreateEgressGateway(gateway)
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
gateway.NodeID, gateway.NetID, err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
apiNode := node.ConvertToAPINode()
logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(apiNode)
runUpdates(&node, true)
}
// swagger:route DELETE /api/nodes/{network}/{nodeid}/deletegateway nodes deleteEgressGateway

View file

@ -308,6 +308,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
IngressInfo: models.IngressInfo{
ExtPeers: make(map[string]models.ExtClientInfo),
},
EgressInfo: make(map[string]models.EgressInfo),
}
logger.Log(1, "peer update for host ", host.ID.String())
peerIndexMap := make(map[string]int)
@ -328,9 +329,9 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
log.Println("no network nodes")
return models.HostPeerUpdate{}, err
}
var extClientPeerMap map[string]models.PeerExtInfo
if node.IsIngressGateway {
extClientPeerMap = make(map[string]models.PeerExtInfo)
var nodePeerMap map[string]models.PeerRouteInfo
if node.IsIngressGateway || node.IsEgressGateway {
nodePeerMap = make(map[string]models.PeerRouteInfo)
}
for _, peer := range currentPeers {
if peer.ID == node.ID {
@ -393,9 +394,9 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
}
peerConfig.AllowedIPs = allowedips
if node.IsIngressGateway {
if node.IsIngressGateway || node.IsEgressGateway {
extClientPeerMap[peerHost.PublicKey.String()] = models.PeerExtInfo{
nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(peer.PrimaryAddress()),
Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
@ -451,7 +452,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
},
ExtPeerKey: extPeerIdAndAddr.ID,
Peers: extClientPeerMap,
Peers: nodePeerMap,
}
}
@ -459,6 +460,12 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
logger.Log(1, "error retrieving external clients:", err.Error())
}
}
if node.IsEgressGateway {
hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
GwPeers: nodePeerMap,
EgressGWCfg: node.EgressGatewayRequest,
}
}
}
return hostPeerUpdate, nil
@ -1108,13 +1115,13 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
continue // if can't parse CIDR
}
nodeEndpointArr := strings.Split(peerHost.EndpointIP.String(), ":") // getting the public ip of node
if ipnet.Contains(net.ParseIP(nodeEndpointArr[0])) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
// getting the public ip of node
if ipnet.Contains(peerHost.EndpointIP) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
logger.Log(2, "egress IP range of ", iprange, " overlaps with ", host.EndpointIP.String(), ", omitting")
continue // skip adding egress range if overlaps with node's ip
}
// TODO: Could put in a lot of great logic to avoid conflicts / bad routes
if ipnet.Contains(net.ParseIP(node.LocalAddress.String())) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
if ipnet.Contains(node.LocalAddress.IP) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress.String(), ", omitting")
continue // skip adding egress range if overlaps with node's local ip
}

View file

@ -27,6 +27,7 @@ type HostPeerUpdate struct {
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
PeerIDs HostPeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
ProxyUpdate ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
EgressInfo map[string]EgressInfo `json:"egress_info" bson:"egress_info" yaml:"egress_info"` // map key is node ID
IngressInfo IngressInfo `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
}
@ -35,8 +36,13 @@ type IngressInfo struct {
ExtPeers map[string]ExtClientInfo `json:"ext_peers" yaml:"ext_peers"`
}
// PeerExtInfo - struct for peer info for an ext. client
type PeerExtInfo struct {
type EgressInfo struct {
GwPeers map[string]PeerRouteInfo
EgressGWCfg EgressGatewayRequest
}
// PeerRouteInfo - struct for peer info for an ext. client
type PeerRouteInfo struct {
PeerAddr net.IPNet `json:"peer_addr" yaml:"peer_addr"`
PeerKey string `json:"peer_key" yaml:"peer_key"`
Allow bool `json:"allow" yaml:"allow"`
@ -44,11 +50,11 @@ type PeerExtInfo struct {
// ExtClientInfo - struct for ext. client and it's peers
type ExtClientInfo struct {
IngGwAddr net.IPNet `json:"ingress_gw_addr" yaml:"ingress_gw_addr"`
Masquerade bool `json:"masquerade" yaml:"masquerade"`
ExtPeerAddr net.IPNet `json:"ext_peer_addr" yaml:"ext_peer_addr"`
ExtPeerKey string `json:"ext_peer_key" yaml:"ext_peer_key"`
Peers map[string]PeerExtInfo `json:"peers" yaml:"peers"`
IngGwAddr net.IPNet `json:"ingress_gw_addr" yaml:"ingress_gw_addr"`
Masquerade bool `json:"masquerade" yaml:"masquerade"`
ExtPeerAddr net.IPNet `json:"ext_peer_addr" yaml:"ext_peer_addr"`
ExtPeerKey string `json:"ext_peer_key" yaml:"ext_peer_key"`
Peers map[string]PeerRouteInfo `json:"peers" yaml:"peers"`
}
// NetworkInfo - struct for network info