Extclient NET-63x (#2286)

* model changes

* additional fields for extclient create

* add DNS to extclient config

* extclient name checks

* update extclient

* nmctl extclient

* final tweaks

* review comments

* add extclientdns to node on ingress creation

* fix to add ingress dns to api (#2296)

---------

Co-authored-by: Aceix <aceixsmartX@gmail.com>
This commit is contained in:
Matthew R Kasun
2023-05-17 10:58:03 -04:00
committed by GitHub
parent 058533db3f
commit 78640f1342
17 changed files with 202 additions and 117 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"strconv"
@@ -230,8 +231,10 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
}
}
defaultDNS := ""
if network.DefaultExtClientDNS != "" {
defaultDNS = "DNS = " + network.DefaultExtClientDNS
if client.DNS != "" {
defaultDNS = "DNS = " + client.DNS
} else if gwnode.IngressDNS != "" {
defaultDNS = "DNS = " + gwnode.IngressDNS
}
defaultMTU := 1420
@@ -321,20 +324,13 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
var extclient models.ExtClient
var customExtClient models.CustomExtClient
err := json.NewDecoder(r.Body).Decode(&customExtClient)
if err == nil {
if customExtClient.ClientID != "" && !validName(customExtClient.ClientID) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest"))
return
}
extclient.ClientID = customExtClient.ClientID
if len(customExtClient.PublicKey) > 0 {
if _, err := wgtypes.ParseKey(customExtClient.PublicKey); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientPubKey, "badrequest"))
return
}
extclient.PublicKey = customExtClient.PublicKey
}
if err := json.NewDecoder(r.Body).Decode(&customExtClient); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
if err := validateExtClient(&extclient, &customExtClient); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
extclient.Network = networkName
@@ -392,7 +388,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
logger.Log(0, "failed to associate client", extclient.ClientID, "to user", userID)
}
extclient.OwnerID = userID
if _, err := logic.UpdateExtClient(extclient.ClientID, extclient.Network, extclient.Enabled, &extclient, extclient.ACLs); err != nil {
if err := logic.SaveExtClient(&extclient); err != nil {
logger.Log(0, "failed to add owner id", userID, "to client", extclient.ClientID)
}
}
@@ -426,9 +422,9 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
var newExtClient models.ExtClient
var update models.CustomExtClient
var oldExtClient models.ExtClient
err := json.NewDecoder(r.Body).Decode(&newExtClient)
err := json.NewDecoder(r.Body).Decode(&update)
if err != nil {
logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
err.Error())
@@ -445,8 +441,8 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if !validName(newExtClient.ClientID) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest"))
if err := validateExtClient(&oldExtClient, &update); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
@@ -466,7 +462,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
// == PRO ==
networkName := params["network"]
var changedID = newExtClient.ClientID != oldExtClient.ClientID
var changedID = update.ClientID != oldExtClient.ClientID
if r.Header.Get("ismaster") != "yes" {
userID := r.Header.Get("user")
_, doesOwn := doesUserOwnClient(userID, params["clientid"], networkName)
@@ -479,17 +475,16 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
if err := pro.DissociateNetworkUserClient(oldExtClient.OwnerID, networkName, oldExtClient.ClientID); err != nil {
logger.Log(0, "failed to dissociate client", oldExtClient.ClientID, "from user", oldExtClient.OwnerID)
}
if err := pro.AssociateNetworkUserClient(oldExtClient.OwnerID, networkName, newExtClient.ClientID); err != nil {
logger.Log(0, "failed to associate client", newExtClient.ClientID, "to user", oldExtClient.OwnerID)
if err := pro.AssociateNetworkUserClient(oldExtClient.OwnerID, networkName, update.ClientID); err != nil {
logger.Log(0, "failed to associate client", update.ClientID, "to user", oldExtClient.OwnerID)
}
}
// == END PRO ==
var changedEnabled = (newExtClient.Enabled != oldExtClient.Enabled) || // indicates there was a change in enablement
len(newExtClient.ACLs) != len(oldExtClient.ACLs)
var changedEnabled = (update.Enabled != oldExtClient.Enabled) // indicates there was a change in enablement
// extra var need as logic.Update changes oldExtClient
currentClient := oldExtClient
newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], newExtClient.Enabled, &oldExtClient, newExtClient.ACLs)
newclient, err := logic.UpdateExtClient(&oldExtClient, &update)
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to update ext client [%s], network [%s]: %v",
@@ -497,7 +492,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
logger.Log(0, r.Header.Get("user"), "updated ext client", newExtClient.ClientID)
logger.Log(0, r.Header.Get("user"), "updated ext client", update.ClientID)
if changedEnabled { // need to send a peer update to the ingress node as enablement of one of it's clients has changed
if ingressNode, err := logic.GetNodeByID(newclient.IngressGatewayID); err == nil {
if err = mq.PublishPeerUpdate(); err != nil {
@@ -509,7 +504,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(newclient)
if changedID {
go func() {
if err := mq.PublishExtClientDNSUpdate(currentClient, newExtClient, networkName); err != nil {
if err := mq.PublishExtClientDNSUpdate(currentClient, *newclient, networkName); err != nil {
logger.Log(1, "error pubishing dns update for extcient update", err.Error())
}
}()
@@ -648,3 +643,35 @@ func doesUserOwnClient(username, clientID, network string) (bool, bool) {
return false, logic.StringSliceContains(netUser.Clients, clientID)
}
// validateExtClient Validates the extclient object
func validateExtClient(extclient *models.ExtClient, customExtClient *models.CustomExtClient) error {
//validate clientid
if customExtClient.ClientID != "" && !validName(customExtClient.ClientID) {
return errInvalidExtClientID
}
extclient.ClientID = customExtClient.ClientID
if len(customExtClient.PublicKey) > 0 {
if _, err := wgtypes.ParseKey(customExtClient.PublicKey); err != nil {
return errInvalidExtClientPubKey
}
extclient.PublicKey = customExtClient.PublicKey
}
//validate extra ips
if len(customExtClient.ExtraAllowedIPs) > 0 {
for _, ip := range customExtClient.ExtraAllowedIPs {
if _, _, err := net.ParseCIDR(ip); err != nil {
return errInvalidExtClientExtraIP
}
}
extclient.ExtraAllowedIPs = customExtClient.ExtraAllowedIPs
}
//validate DNS
if customExtClient.DNS != "" {
if ip := net.ParseIP(customExtClient.DNS); ip == nil {
return errInvalidExtClientDNS
}
extclient.DNS = customExtClient.DNS
}
return nil
}