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,10 +4,16 @@ import (
"fmt" "fmt"
"github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var extClientID string var (
extClientID string
publicKey string
dns string
allowedips []string
)
var extClientCreateCmd = &cobra.Command{ var extClientCreateCmd = &cobra.Command{
Use: "create [NETWORK NAME] [NODE ID]", Use: "create [NETWORK NAME] [NODE ID]",
@@ -15,12 +21,22 @@ var extClientCreateCmd = &cobra.Command{
Short: "Create an External Client", Short: "Create an External Client",
Long: `Create an External Client`, Long: `Create an External Client`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
functions.CreateExtClient(args[0], args[1], extClientID) extClient := models.CustomExtClient{
ClientID: extClientID,
PublicKey: publicKey,
DNS: dns,
ExtraAllowedIPs: allowedips,
}
functions.CreateExtClient(args[0], args[1], extClient)
fmt.Println("Success") fmt.Println("Success")
}, },
} }
func init() { func init() {
extClientCreateCmd.Flags().StringVar(&extClientID, "id", "", "ID of the external client") extClientCreateCmd.Flags().StringVar(&extClientID, "id", "", "ID of the external client")
extClientCreateCmd.Flags().StringVar(&publicKey, "public_key", "", "updated public key of the external client")
extClientCreateCmd.Flags().StringVar(&dns, "dns", "", "updated DNS of the external client")
extClientCreateCmd.Flags().StringSliceVar(&allowedips, "allowedips", []string{}, "updated extra allowed IPs of the external client")
rootCmd.AddCommand(extClientCreateCmd) rootCmd.AddCommand(extClientCreateCmd)
} }

View File

@@ -12,14 +12,6 @@ import (
var ( var (
extClientUpdateFile string extClientUpdateFile string
description string
privateKey string
publicKey string
address string
address6 string
ingressGatewayID string
ingressGatewayEndpoint string
ownerID string
) )
var extClientUpdateCmd = &cobra.Command{ var extClientUpdateCmd = &cobra.Command{
@@ -31,7 +23,7 @@ var extClientUpdateCmd = &cobra.Command{
var ( var (
network = args[0] network = args[0]
clientID = args[1] clientID = args[1]
extClient = &models.ExtClient{} extClient = &models.CustomExtClient{}
) )
if extClientUpdateFile != "" { if extClientUpdateFile != "" {
content, err := os.ReadFile(extClientUpdateFile) content, err := os.ReadFile(extClientUpdateFile)
@@ -42,30 +34,19 @@ var extClientUpdateCmd = &cobra.Command{
log.Fatal(err) log.Fatal(err)
} }
} else { } else {
extClient.ClientID = clientID extClient.ClientID = extClientID
extClient.Description = description
extClient.PrivateKey = privateKey
extClient.PublicKey = publicKey extClient.PublicKey = publicKey
extClient.Network = network extClient.DNS = dns
extClient.Address = address
extClient.Address6 = address6
extClient.IngressGatewayID = ingressGatewayID
extClient.IngressGatewayEndpoint = ingressGatewayEndpoint
extClient.OwnerID = ownerID
} }
functions.PrettyPrint(functions.UpdateExtClient(network, clientID, extClient)) functions.PrettyPrint(functions.UpdateExtClient(network, clientID, extClient))
}, },
} }
func init() { func init() {
extClientUpdateCmd.Flags().StringVar(&extClientID, "id", "", "updated ID of the external client")
extClientUpdateCmd.Flags().StringVar(&extClientUpdateFile, "file", "", "Filepath of updated external client definition in JSON") extClientUpdateCmd.Flags().StringVar(&extClientUpdateFile, "file", "", "Filepath of updated external client definition in JSON")
extClientUpdateCmd.Flags().StringVar(&description, "desc", "", "Description of the external client") extClientUpdateCmd.Flags().StringVar(&publicKey, "public_key", "", "updated public key of the external client")
extClientUpdateCmd.Flags().StringVar(&privateKey, "private_key", "", "Filepath of updated external client definition in JSON") extClientUpdateCmd.Flags().StringVar(&dns, "dns", "", "updated DNS of the external client")
extClientUpdateCmd.Flags().StringVar(&publicKey, "public_key", "", "Filepath of updated external client definition in JSON") extClientUpdateCmd.Flags().StringSliceVar(&allowedips, "allowedips", []string{}, "updated extra allowed IPs of the external client")
extClientUpdateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the external client")
extClientUpdateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the external client")
extClientUpdateCmd.Flags().StringVar(&ingressGatewayID, "ingress_gateway_id", "", "ID of the ingress gateway")
extClientUpdateCmd.Flags().StringVar(&ingressGatewayEndpoint, "ingress_gateway_endpoint", "", "Endpoint of the ingress gateway")
extClientUpdateCmd.Flags().StringVar(&ownerID, "owner_id", "", "External Client owner's ID")
rootCmd.AddCommand(extClientUpdateCmd) rootCmd.AddCommand(extClientUpdateCmd)
} }

View File

@@ -45,7 +45,6 @@ var networkCreateCmd = &cobra.Command{
if allowManualSignUp { if allowManualSignUp {
network.AllowManualSignUp = "yes" network.AllowManualSignUp = "yes"
} }
network.DefaultExtClientDNS = defaultExtClientDNS
network.DefaultMTU = int32(defaultMTU) network.DefaultMTU = int32(defaultMTU)
} }
functions.PrettyPrint(functions.CreateNetwork(network)) functions.PrettyPrint(functions.CreateNetwork(network))
@@ -61,7 +60,6 @@ func init() {
networkCreateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?") networkCreateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?")
networkCreateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?") networkCreateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?")
networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface") networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
networkCreateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
networkCreateCmd.Flags().IntVar(&defaultListenPort, "listen_port", 51821, "Default wireguard port each node will attempt to use") networkCreateCmd.Flags().IntVar(&defaultListenPort, "listen_port", 51821, "Default wireguard port each node will attempt to use")
networkCreateCmd.Flags().IntVar(&nodeLimit, "node_limit", 999999999, "Maximum number of nodes that can be associated with this network") networkCreateCmd.Flags().IntVar(&nodeLimit, "node_limit", 999999999, "Maximum number of nodes that can be associated with this network")
networkCreateCmd.Flags().IntVar(&defaultKeepalive, "keep_alive", 20, "Keep Alive in seconds") networkCreateCmd.Flags().IntVar(&defaultKeepalive, "keep_alive", 20, "Keep Alive in seconds")

View File

@@ -12,6 +12,5 @@ var (
nodeLimit int nodeLimit int
defaultKeepalive int defaultKeepalive int
allowManualSignUp bool allowManualSignUp bool
defaultExtClientDNS string
defaultMTU int defaultMTU int
) )

View File

@@ -28,14 +28,8 @@ func GetExtClientConfig(networkName, clientID string) string {
} }
// CreateExtClient - create an external client // CreateExtClient - create an external client
func CreateExtClient(networkName, nodeID, extClientID string) { func CreateExtClient(networkName, nodeID string, extClient models.CustomExtClient) {
if extClientID != "" { request[any](http.MethodPost, fmt.Sprintf("/api/extclients/%s/%s", networkName, nodeID), extClient)
request[any](http.MethodPost, fmt.Sprintf("/api/extclients/%s/%s", networkName, nodeID), &models.CustomExtClient{
ClientID: extClientID,
})
} else {
request[any](http.MethodPost, fmt.Sprintf("/api/extclients/%s/%s", networkName, nodeID), nil)
}
} }
// DeleteExtClient - delete an external client // DeleteExtClient - delete an external client
@@ -44,6 +38,6 @@ func DeleteExtClient(networkName, clientID string) *models.SuccessResponse {
} }
// UpdateExtClient - update an external client // UpdateExtClient - update an external client
func UpdateExtClient(networkName, clientID string, payload *models.ExtClient) *models.ExtClient { func UpdateExtClient(networkName, clientID string, payload *models.CustomExtClient) *models.ExtClient {
return request[models.ExtClient](http.MethodPut, fmt.Sprintf("/api/extclients/%s/%s", networkName, clientID), payload) return request[models.ExtClient](http.MethodPut, fmt.Sprintf("/api/extclients/%s/%s", networkName, clientID), payload)
} }

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net"
"net/http" "net/http"
"strconv" "strconv"
@@ -230,8 +231,10 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
} }
} }
defaultDNS := "" defaultDNS := ""
if network.DefaultExtClientDNS != "" { if client.DNS != "" {
defaultDNS = "DNS = " + network.DefaultExtClientDNS defaultDNS = "DNS = " + client.DNS
} else if gwnode.IngressDNS != "" {
defaultDNS = "DNS = " + gwnode.IngressDNS
} }
defaultMTU := 1420 defaultMTU := 1420
@@ -321,21 +324,14 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
var extclient models.ExtClient var extclient models.ExtClient
var customExtClient models.CustomExtClient var customExtClient models.CustomExtClient
err := json.NewDecoder(r.Body).Decode(&customExtClient) if err := json.NewDecoder(r.Body).Decode(&customExtClient); err != nil {
if err == nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
if customExtClient.ClientID != "" && !validName(customExtClient.ClientID) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest"))
return return
} }
extclient.ClientID = customExtClient.ClientID if err := validateExtClient(&extclient, &customExtClient); err != nil {
if len(customExtClient.PublicKey) > 0 { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
if _, err := wgtypes.ParseKey(customExtClient.PublicKey); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientPubKey, "badrequest"))
return return
} }
extclient.PublicKey = customExtClient.PublicKey
}
}
extclient.Network = networkName extclient.Network = networkName
extclient.IngressGatewayID = nodeid extclient.IngressGatewayID = nodeid
@@ -392,7 +388,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
logger.Log(0, "failed to associate client", extclient.ClientID, "to user", userID) logger.Log(0, "failed to associate client", extclient.ClientID, "to user", userID)
} }
extclient.OwnerID = 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) 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 params = mux.Vars(r)
var newExtClient models.ExtClient var update models.CustomExtClient
var oldExtClient models.ExtClient var oldExtClient models.ExtClient
err := json.NewDecoder(r.Body).Decode(&newExtClient) err := json.NewDecoder(r.Body).Decode(&update)
if err != nil { if err != nil {
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
err.Error()) err.Error())
@@ -445,8 +441,8 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return return
} }
if !validName(newExtClient.ClientID) { if err := validateExtClient(&oldExtClient, &update); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest")) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return return
} }
data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key) data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
@@ -466,7 +462,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
// == PRO == // == PRO ==
networkName := params["network"] networkName := params["network"]
var changedID = newExtClient.ClientID != oldExtClient.ClientID var changedID = update.ClientID != oldExtClient.ClientID
if r.Header.Get("ismaster") != "yes" { if r.Header.Get("ismaster") != "yes" {
userID := r.Header.Get("user") userID := r.Header.Get("user")
_, doesOwn := doesUserOwnClient(userID, params["clientid"], networkName) _, 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 { if err := pro.DissociateNetworkUserClient(oldExtClient.OwnerID, networkName, oldExtClient.ClientID); err != nil {
logger.Log(0, "failed to dissociate client", oldExtClient.ClientID, "from user", oldExtClient.OwnerID) logger.Log(0, "failed to dissociate client", oldExtClient.ClientID, "from user", oldExtClient.OwnerID)
} }
if err := pro.AssociateNetworkUserClient(oldExtClient.OwnerID, networkName, newExtClient.ClientID); err != nil { if err := pro.AssociateNetworkUserClient(oldExtClient.OwnerID, networkName, update.ClientID); err != nil {
logger.Log(0, "failed to associate client", newExtClient.ClientID, "to user", oldExtClient.OwnerID) logger.Log(0, "failed to associate client", update.ClientID, "to user", oldExtClient.OwnerID)
} }
} }
// == END PRO == // == END PRO ==
var changedEnabled = (newExtClient.Enabled != oldExtClient.Enabled) || // indicates there was a change in enablement var changedEnabled = (update.Enabled != oldExtClient.Enabled) // indicates there was a change in enablement
len(newExtClient.ACLs) != len(oldExtClient.ACLs)
// extra var need as logic.Update changes oldExtClient // extra var need as logic.Update changes oldExtClient
currentClient := 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 { if err != nil {
logger.Log(0, r.Header.Get("user"), logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to update ext client [%s], network [%s]: %v", 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")) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return 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 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 ingressNode, err := logic.GetNodeByID(newclient.IngressGatewayID); err == nil {
if err = mq.PublishPeerUpdate(); 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) json.NewEncoder(w).Encode(newclient)
if changedID { if changedID {
go func() { 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()) 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) 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
}

View File

@@ -520,13 +520,10 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
nodeid := params["nodeid"] nodeid := params["nodeid"]
netid := params["network"] netid := params["network"]
type failoverData struct { var request models.IngressRequest
Failover bool `json:"failover"` json.NewDecoder(r.Body).Decode(&request)
}
var failoverReqBody failoverData
json.NewDecoder(r.Body).Decode(&failoverReqBody)
node, err := logic.CreateIngressGateway(netid, nodeid, failoverReqBody.Failover) node, err := logic.CreateIngressGateway(netid, nodeid, request)
if err != nil { if err != nil {
logger.Log(0, r.Header.Get("user"), logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v", fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
@@ -535,7 +532,7 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
return return
} }
if servercfg.Is_EE && failoverReqBody.Failover { if servercfg.Is_EE && request.Failover {
if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil { if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil {
logger.Log(1, "failed to reset failover list during failover create", node.ID.String(), node.Network) logger.Log(1, "failed to reset failover list during failover create", node.ID.String(), node.Network)
} }

View File

@@ -7,10 +7,22 @@ import (
var ( var (
errInvalidExtClientPubKey = errors.New("incorrect ext client public key") errInvalidExtClientPubKey = errors.New("incorrect ext client public key")
errInvalidExtClientID = errors.New("ext client ID must be alphanumderic and/or dashes") errInvalidExtClientID = errors.New("ext client ID must be alphanumderic and/or dashes and less that 15 chars")
errInvalidExtClientExtraIP = errors.New("ext client extra ip must be a valid cidr")
errInvalidExtClientDNS = errors.New("ext client dns must be a valid ip address")
) )
// allow only dashes and alphaneumeric for ext client and node names // allow only dashes and alphaneumeric for ext client and node names
func validName(name string) bool { func validName(name string) bool {
return regexp.MustCompile("^[a-zA-Z0-9-]+$").MatchString(name) reg, err := regexp.Compile("^[a-zA-Z0-9-]+$")
if err != nil {
return false
}
if !reg.MatchString(name) {
return false
}
if len(name) > 15 {
return false
}
return true
} }

51
controllers/regex_test.go Normal file
View File

@@ -0,0 +1,51 @@
package controller
import "testing"
// TestValidName tests the validName function
func TestValidName(t *testing.T) {
type args struct {
Name string
}
tests := []struct {
Name string
Args args
Want bool
}{
{
Name: "validName",
Args: args{
Name: "TestvalidName",
},
Want: true,
},
{
Name: "invalidName",
Args: args{
Name: "Test*Name",
},
Want: false,
},
{
Name: "nametoolong",
Args: args{
Name: "TestvalidNameTestvalidName",
},
Want: false,
},
{
Name: "maxlength",
Args: args{
Name: "123456789012345",
},
Want: true,
},
}
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
if got := validName(tt.Args.Name); got != tt.Want {
t.Errorf("validName() = %v, want %v", got, tt.Want)
}
})
}
}

View File

@@ -19,7 +19,6 @@ var (
} }
testExternalClient = &models.ExtClient{ testExternalClient = &models.ExtClient{
ClientID: "testExtClient", ClientID: "testExtClient",
Description: "ext client for testing",
} }
) )

View File

@@ -174,6 +174,11 @@ func CreateExtClient(extclient *models.ExtClient) error {
} }
extclient.LastModified = time.Now().Unix() extclient.LastModified = time.Now().Unix()
return SaveExtClient(extclient)
}
// SaveExtClient - saves an ext client to database
func SaveExtClient(extclient *models.ExtClient) error {
key, err := GetRecordKey(extclient.ClientID, extclient.Network) key, err := GetRecordKey(extclient.ClientID, extclient.Network)
if err != nil { if err != nil {
return err return err
@@ -188,35 +193,27 @@ func CreateExtClient(extclient *models.ExtClient) error {
return SetNetworkNodesLastModified(extclient.Network) return SetNetworkNodesLastModified(extclient.Network)
} }
// UpdateExtClient - only supports name changes right now // UpdateExtClient - updates an ext client with new values
func UpdateExtClient(newclientid string, network string, enabled bool, client *models.ExtClient, newACLs map[string]struct{}) (*models.ExtClient, error) { func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) (*models.ExtClient, error) {
err := DeleteExtClient(network, client.ClientID) new := old
err := DeleteExtClient(old.Network, old.ClientID)
if err != nil { if err != nil {
return client, err return new, err
} }
if newclientid != client.ClientID { // name change only new.ClientID = update.ClientID
client.ClientID = newclientid if update.PublicKey != "" && old.PublicKey != update.PublicKey {
client.LastModified = time.Now().Unix() new.PublicKey = update.PublicKey
data, err := json.Marshal(&client)
if err != nil {
return nil, err
} }
key, err := GetRecordKey(client.ClientID, client.Network) if update.DNS != "" && update.DNS != old.DNS {
if err != nil { new.DNS = update.DNS
return nil, err
} }
if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil { if update.Enabled != old.Enabled {
return client, err new.Enabled = update.Enabled
} }
return client, nil if update.ExtraAllowedIPs != nil && StringDifference(old.ExtraAllowedIPs, update.ExtraAllowedIPs) != nil {
new.ExtraAllowedIPs = update.ExtraAllowedIPs
} }
client.ClientID = newclientid return new, CreateExtClient(new)
client.Enabled = enabled
SetClientACLs(client, newACLs)
if err = CreateExtClient(client); err != nil {
return client, err
}
return client, err
} }
// GetExtClientsByID - gets the clients of attached gateway // GetExtClientsByID - gets the clients of attached gateway

View File

@@ -96,7 +96,7 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
} }
// CreateIngressGateway - creates an ingress gateway // CreateIngressGateway - creates an ingress gateway
func CreateIngressGateway(netid string, nodeid string, failover bool) (models.Node, error) { func CreateIngressGateway(netid string, nodeid string, ingress models.IngressRequest) (models.Node, error) {
node, err := GetNodeByID(nodeid) node, err := GetNodeByID(nodeid)
if err != nil { if err != nil {
@@ -120,8 +120,9 @@ func CreateIngressGateway(netid string, nodeid string, failover bool) (models.No
node.IsIngressGateway = true node.IsIngressGateway = true
node.IngressGatewayRange = network.AddressRange node.IngressGatewayRange = network.AddressRange
node.IngressGatewayRange6 = network.AddressRange6 node.IngressGatewayRange6 = network.AddressRange6
node.IngressDNS = ingress.ExtclientDNS
node.SetLastModified() node.SetLastModified()
if failover && servercfg.Is_EE { if ingress.Failover && servercfg.Is_EE {
node.Failover = true node.Failover = true
} }
data, err := json.Marshal(&node) data, err := json.Marshal(&node)

View File

@@ -32,6 +32,7 @@ type ApiNode struct {
RelayAddrs []string `json:"relayaddrs"` RelayAddrs []string `json:"relayaddrs"`
FailoverNode string `json:"failovernode"` FailoverNode string `json:"failovernode"`
DNSOn bool `json:"dnson"` DNSOn bool `json:"dnson"`
IngressDns string `json:"ingressdns"`
Server string `json:"server"` Server string `json:"server"`
InternetGateway string `json:"internetgateway"` InternetGateway string `json:"internetgateway"`
Connected bool `json:"connected"` Connected bool `json:"connected"`
@@ -61,6 +62,7 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6 convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
convertedNode.DNSOn = a.DNSOn convertedNode.DNSOn = a.DNSOn
convertedNode.IngressDNS = a.IngressDns
convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest
convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled
convertedNode.PersistentKeepalive = time.Second * time.Duration(a.PersistentKeepalive) convertedNode.PersistentKeepalive = time.Second * time.Duration(a.PersistentKeepalive)
@@ -148,6 +150,7 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
apiNode.FailoverNode = "" apiNode.FailoverNode = ""
} }
apiNode.DNSOn = nm.DNSOn apiNode.DNSOn = nm.DNSOn
apiNode.IngressDns = nm.IngressDNS
apiNode.Server = nm.Server apiNode.Server = nm.Server
apiNode.InternetGateway = nm.InternetGateway.String() apiNode.InternetGateway = nm.InternetGateway.String()
if isEmptyAddr(apiNode.InternetGateway) { if isEmptyAddr(apiNode.InternetGateway) {

View File

@@ -3,12 +3,13 @@ package models
// ExtClient - struct for external clients // ExtClient - struct for external clients
type ExtClient struct { type ExtClient struct {
ClientID string `json:"clientid" bson:"clientid"` ClientID string `json:"clientid" bson:"clientid"`
Description string `json:"description" bson:"description"`
PrivateKey string `json:"privatekey" bson:"privatekey"` PrivateKey string `json:"privatekey" bson:"privatekey"`
PublicKey string `json:"publickey" bson:"publickey"` PublicKey string `json:"publickey" bson:"publickey"`
Network string `json:"network" bson:"network"` Network string `json:"network" bson:"network"`
DNS string `json:"dns" bson:"dns"`
Address string `json:"address" bson:"address"` Address string `json:"address" bson:"address"`
Address6 string `json:"address6" bson:"address6"` Address6 string `json:"address6" bson:"address6"`
ExtraAllowedIPs []string `json:"extraallowedips" bson:"extraallowedips"`
IngressGatewayID string `json:"ingressgatewayid" bson:"ingressgatewayid"` IngressGatewayID string `json:"ingressgatewayid" bson:"ingressgatewayid"`
IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"` IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
LastModified int64 `json:"lastmodified" bson:"lastmodified"` LastModified int64 `json:"lastmodified" bson:"lastmodified"`
@@ -16,3 +17,12 @@ type ExtClient struct {
OwnerID string `json:"ownerid" bson:"ownerid"` OwnerID string `json:"ownerid" bson:"ownerid"`
ACLs map[string]struct{} `json:"acls,omitempty" bson:"acls,omitempty"` ACLs map[string]struct{} `json:"acls,omitempty" bson:"acls,omitempty"`
} }
// CustomExtClient - struct for CustomExtClient params
type CustomExtClient struct {
ClientID string `json:"clientid,omitempty"`
PublicKey string `json:"publickey,omitempty"`
DNS string `json:"dns,omitempty"`
ExtraAllowedIPs []string `json:"extraallowedips,omitempty"`
Enabled bool `json:"enabled,omitempty"`
}

View File

@@ -23,7 +23,6 @@ type Network struct {
IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"` IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"` IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"` DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
DefaultExtClientDNS string `json:"defaultextclientdns" bson:"defaultextclientdns"`
DefaultMTU int32 `json:"defaultmtu" bson:"defaultmtu"` DefaultMTU int32 `json:"defaultmtu" bson:"defaultmtu"`
DefaultACL string `json:"defaultacl" bson:"defaultacl" yaml:"defaultacl" validate:"checkyesorno"` DefaultACL string `json:"defaultacl" bson:"defaultacl" yaml:"defaultacl" validate:"checkyesorno"`
ProSettings *promodels.ProNetwork `json:"prosettings,omitempty" bson:"prosettings,omitempty" yaml:"prosettings,omitempty"` ProSettings *promodels.ProNetwork `json:"prosettings,omitempty" bson:"prosettings,omitempty" yaml:"prosettings,omitempty"`

View File

@@ -69,6 +69,7 @@ type CommonNode struct {
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
IngressDNS string `json:"ingressdns" yaml:"ingressdns"`
DNSOn bool `json:"dnson" yaml:"dnson"` DNSOn bool `json:"dnson" yaml:"dnson"`
PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"` PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"`
} }

View File

@@ -14,12 +14,6 @@ const (
PLACEHOLDER_TOKEN_TEXT = "ACCESS_TOKEN" PLACEHOLDER_TOKEN_TEXT = "ACCESS_TOKEN"
) )
// CustomExtClient - struct for CustomExtClient params
type CustomExtClient struct {
ClientID string `json:"clientid"`
PublicKey string `json:"publickey,omitempty"`
}
// AuthParams - struct for auth params // AuthParams - struct for auth params
type AuthParams struct { type AuthParams struct {
MacAddress string `json:"macaddress"` MacAddress string `json:"macaddress"`
@@ -170,6 +164,12 @@ type HostRelayRequest struct {
RelayedHosts []string `json:"relayed_hosts"` RelayedHosts []string `json:"relayed_hosts"`
} }
// IngressRequest - ingress request struct
type IngressRequest struct {
ExtclientDNS string `json:"extclientdns"`
Failover bool `json:"failover"`
}
// ServerUpdateData - contains data to configure server // ServerUpdateData - contains data to configure server
// and if it should set peers // and if it should set peers
type ServerUpdateData struct { type ServerUpdateData struct {