netmaker/pro/controllers/inet_gws.go
Abhishek K 5849e0e2e1
NET-1932: sort out acls into CE and PRO (#3460)
* move relevant acl and tag code to CE and Pro pkgs

* intialise pro acl funcs

* list gateways by user access

* check user gw access by policies

* filter out user policies on CE

* filter out tagged policies on CE

* fix ce acl comms

* allow gateways tag

* allow gateway tag  on CE, remove failover and gw check on acl policy

* add gw rules func to pro

* add inet gw support on CE

* add egress acl API

* add egress acl API

* fix(go): set is_gw when converting api node to server node;

* fix(go): set is_gw when converting api node to server node;

* fix policy validity checker for inet gws

* move dns option to host model

* fix node removal from egress policy on delete

* add migration logic for ManageDNS

* fix dns json field

* fix nil error on node tags

* add egress info to relayed nodes

---------

Co-authored-by: Vishal Dalwadi <dalwadivishal26@gmail.com>
2025-06-02 13:05:10 +05:30

206 lines
6 KiB
Go

package controllers
import (
"encoding/json"
"errors"
"net/http"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mq"
proLogic "github.com/gravitl/netmaker/pro/logic"
"github.com/gravitl/netmaker/servercfg"
)
// InetHandlers - handlers for internet gw
func InetHandlers(r *mux.Router) {
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))).
Methods(http.MethodPost)
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))).
Methods(http.MethodPut)
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))).
Methods(http.MethodDelete)
}
// @Summary Create an internet gateway
// @Router /api/nodes/{network}/{nodeid}/inet_gw [post]
// @Tags PRO
// @Accept json
// @Param network path string true "Network ID"
// @Param nodeid path string true "Node ID"
// @Param body body models.InetNodeReq true "Internet gateway request"
// @Success 200 {object} models.Node
// @Failure 400 {object} models.ErrorResponse
// @Failure 500 {object} models.ErrorResponse
func createInternetGw(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
w.Header().Set("Content-Type", "application/json")
nodeid := params["nodeid"]
netid := params["network"]
node, err := logic.ValidateParams(nodeid, netid)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
if node.EgressDetails.IsInternetGateway {
logic.ReturnSuccessResponse(w, r, "node is already acting as internet gateway")
return
}
var request models.InetNodeReq
err = json.NewDecoder(r.Body).Decode(&request)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
host, err := logic.GetHost(node.HostID.String())
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if host.OS != models.OS_Types.Linux {
logic.ReturnErrorResponse(
w,
r,
logic.FormatError(
errors.New("only linux nodes can be made internet gws"),
"badrequest",
),
)
return
}
err = logic.ValidateInetGwReq(node, request, false)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
logic.SetInternetGw(&node, request)
if servercfg.IsPro {
if _, exists := proLogic.FailOverExists(node.Network); exists {
go func() {
proLogic.ResetFailedOverPeer(&node)
mq.PublishPeerUpdate(false)
}()
}
}
if node.IsGw && node.IngressDNS == "" {
node.IngressDNS = "1.1.1.1"
}
err = logic.UpsertNode(&node)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
apiNode := node.ConvertToAPINode()
logger.Log(
1,
r.Header.Get("user"),
"created ingress gateway on node",
nodeid,
"on network",
netid,
)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(apiNode)
go mq.PublishPeerUpdate(false)
}
// @Summary Update an internet gateway
// @Router /api/nodes/{network}/{nodeid}/inet_gw [put]
// @Tags PRO
// @Accept json
// @Param network path string true "Network ID"
// @Param nodeid path string true "Node ID"
// @Param body body models.InetNodeReq true "Internet gateway request"
// @Success 200 {object} models.Node
// @Failure 400 {object} models.ErrorResponse
// @Failure 500 {object} models.ErrorResponse
func updateInternetGw(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
w.Header().Set("Content-Type", "application/json")
nodeid := params["nodeid"]
netid := params["network"]
node, err := logic.ValidateParams(nodeid, netid)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
var request models.InetNodeReq
err = json.NewDecoder(r.Body).Decode(&request)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
if !node.EgressDetails.IsInternetGateway {
logic.ReturnErrorResponse(
w,
r,
logic.FormatError(errors.New("node is not a internet gw"), "badrequest"),
)
return
}
err = logic.ValidateInetGwReq(node, request, true)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
logic.UnsetInternetGw(&node)
logic.SetInternetGw(&node, request)
err = logic.UpsertNode(&node)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
apiNode := node.ConvertToAPINode()
logger.Log(
1,
r.Header.Get("user"),
"created ingress gateway on node",
nodeid,
"on network",
netid,
)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(apiNode)
go mq.PublishPeerUpdate(false)
}
// @Summary Delete an internet gateway
// @Router /api/nodes/{network}/{nodeid}/inet_gw [delete]
// @Tags PRO
// @Param network path string true "Network ID"
// @Param nodeid path string true "Node ID"
// @Success 200 {object} models.Node
// @Failure 400 {object} models.ErrorResponse
// @Failure 500 {object} models.ErrorResponse
func deleteInternetGw(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
w.Header().Set("Content-Type", "application/json")
nodeid := params["nodeid"]
netid := params["network"]
node, err := logic.ValidateParams(nodeid, netid)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
logic.UnsetInternetGw(&node)
err = logic.UpsertNode(&node)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
apiNode := node.ConvertToAPINode()
logger.Log(
1,
r.Header.Get("user"),
"created ingress gateway on node",
nodeid,
"on network",
netid,
)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(apiNode)
go mq.PublishPeerUpdate(false)
}