mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-21 15:56:07 +08:00
Merge pull request #793 from gravitl/feature_v0.11.0_commsnet
Feature v0.11.0 commsnet
This commit is contained in:
commit
0b1bf1b9aa
|
@ -260,7 +260,7 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
logic.DeleteNetwork(network.NetID)
|
||||
if err == nil {
|
||||
err = errors.New("Failed to add server to network " + network.DisplayName)
|
||||
err = errors.New("Failed to add server to network " + network.NetID)
|
||||
}
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
|
|
|
@ -3,7 +3,6 @@ package controller
|
|||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
|
@ -24,7 +23,8 @@ func TestCreateNetwork(t *testing.T) {
|
|||
var network models.Network
|
||||
network.NetID = "skynet"
|
||||
network.AddressRange = "10.0.0.1/24"
|
||||
network.DisplayName = "mynetwork"
|
||||
// if tests break - check here (removed displayname)
|
||||
//network.DisplayName = "mynetwork"
|
||||
|
||||
err := logic.CreateNetwork(network)
|
||||
assert.Nil(t, err)
|
||||
|
@ -61,20 +61,6 @@ func TestDeleteNetwork(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestKeyUpdate(t *testing.T) {
|
||||
t.Skip() //test is failing on last assert --- not sure why
|
||||
database.InitializeDatabase()
|
||||
createNet()
|
||||
existing, err := logic.GetNetwork("skynet")
|
||||
assert.Nil(t, err)
|
||||
time.Sleep(time.Second * 1)
|
||||
network, err := logic.KeyUpdate("skynet")
|
||||
assert.Nil(t, err)
|
||||
network, err = logic.GetNetwork("skynet")
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, network.KeyUpdateTimeStamp, existing.KeyUpdateTimeStamp)
|
||||
}
|
||||
|
||||
func TestCreateKey(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
createNet()
|
||||
|
@ -245,28 +231,6 @@ func TestValidateNetworkUpdate(t *testing.T) {
|
|||
},
|
||||
errMessage: "Field validation for 'AddressRange6' failed on the 'cidr' tag",
|
||||
},
|
||||
|
||||
{
|
||||
testname: "BadDisplayName",
|
||||
network: models.Network{
|
||||
DisplayName: "skynet*",
|
||||
},
|
||||
errMessage: "Field validation for 'DisplayName' failed on the 'alphanum' tag",
|
||||
},
|
||||
{
|
||||
testname: "DisplayNameTooLong",
|
||||
network: models.Network{
|
||||
DisplayName: "Thisisareallylongdisplaynamethatistoolong",
|
||||
},
|
||||
errMessage: "Field validation for 'DisplayName' failed on the 'max' tag",
|
||||
},
|
||||
{
|
||||
testname: "DisplayNameTooShort",
|
||||
network: models.Network{
|
||||
DisplayName: "1",
|
||||
},
|
||||
errMessage: "Field validation for 'DisplayName' failed on the 'min' tag",
|
||||
},
|
||||
{
|
||||
testname: "InvalidNetID",
|
||||
network: models.Network{
|
||||
|
@ -309,20 +273,6 @@ func TestValidateNetworkUpdate(t *testing.T) {
|
|||
},
|
||||
errMessage: "Field validation for 'LocalRange' failed on the 'cidr' tag",
|
||||
},
|
||||
{
|
||||
testname: "CheckInIntervalTooBig",
|
||||
network: models.Network{
|
||||
DefaultCheckInInterval: 100001,
|
||||
},
|
||||
errMessage: "Field validation for 'DefaultCheckInInterval' failed on the 'max' tag",
|
||||
},
|
||||
{
|
||||
testname: "CheckInIntervalTooSmall",
|
||||
network: models.Network{
|
||||
DefaultCheckInInterval: 1,
|
||||
},
|
||||
errMessage: "Field validation for 'DefaultCheckInInterval' failed on the 'min' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.testname, func(t *testing.T) {
|
||||
|
@ -346,7 +296,6 @@ func createNet() {
|
|||
var network models.Network
|
||||
network.NetID = "skynet"
|
||||
network.AddressRange = "10.0.0.1/24"
|
||||
network.DisplayName = "mynetwork"
|
||||
_, err := logic.GetNetwork("skynet")
|
||||
if err != nil {
|
||||
logic.CreateNetwork(network)
|
||||
|
|
|
@ -539,7 +539,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
|
|||
returnErrorResponse(w, r, formatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
newNode.PullChanges = "yes"
|
||||
relayupdate := false
|
||||
if node.IsRelay == "yes" && len(newNode.RelayAddrs) > 0 {
|
||||
if len(newNode.RelayAddrs) != len(node.RelayAddrs) {
|
||||
|
|
|
@ -107,26 +107,6 @@ func NetworkExists(name string) (bool, error) {
|
|||
return len(network) > 0, nil
|
||||
}
|
||||
|
||||
// IsNetworkDisplayNameUnique - checks if network display name unique
|
||||
func IsNetworkDisplayNameUnique(name string) (bool, error) {
|
||||
|
||||
isunique := true
|
||||
|
||||
dbs, err := logic.GetNetworks()
|
||||
if err != nil {
|
||||
return database.IsEmptyRecord(err), err
|
||||
}
|
||||
|
||||
for i := 0; i < len(dbs); i++ {
|
||||
|
||||
if name == dbs[i].DisplayName {
|
||||
isunique = false
|
||||
}
|
||||
}
|
||||
|
||||
return isunique, nil
|
||||
}
|
||||
|
||||
// IsKeyValidGlobal - checks if a key is valid globally
|
||||
func IsKeyValidGlobal(keyvalue string) bool {
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
|
|||
node.PostUp = postUpCmd
|
||||
node.PostDown = postDownCmd
|
||||
node.SetLastModified()
|
||||
node.PullChanges = "yes"
|
||||
nodeData, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return node, err
|
||||
|
@ -94,7 +93,6 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
|
|||
node.PostDown = "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE"
|
||||
}
|
||||
node.SetLastModified()
|
||||
node.PullChanges = "yes"
|
||||
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
|
@ -142,7 +140,6 @@ func CreateIngressGateway(netid string, nodeid string) (models.Node, error) {
|
|||
node.SetLastModified()
|
||||
node.PostUp = postUpCmd
|
||||
node.PostDown = postDownCmd
|
||||
node.PullChanges = "yes"
|
||||
node.UDPHolePunch = "no"
|
||||
|
||||
data, err := json.Marshal(&node)
|
||||
|
@ -177,7 +174,6 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, error
|
|||
node.LastModified = time.Now().Unix()
|
||||
node.IsIngressGateway = "no"
|
||||
node.IngressGatewayRange = ""
|
||||
node.PullChanges = "yes"
|
||||
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
|
@ -68,7 +67,6 @@ func CreateNetwork(network models.Network) error {
|
|||
network.SetDefaults()
|
||||
network.SetNodesLastModified()
|
||||
network.SetNetworkLastModified()
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
|
||||
err := ValidateNetwork(&network, false)
|
||||
if err != nil {
|
||||
|
@ -106,7 +104,6 @@ func NetworkNodesUpdatePullChanges(networkName string) error {
|
|||
return err
|
||||
}
|
||||
if node.Network == networkName {
|
||||
node.PullChanges = "yes"
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -446,7 +443,6 @@ func RemoveNetworkNodeIPv6Addresses(networkName string) error {
|
|||
if node.Network == networkName {
|
||||
node.IsDualStack = "no"
|
||||
node.Address6 = ""
|
||||
node.PullChanges = "yes"
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -488,7 +484,6 @@ func UpdateNetworkNodeAddresses(networkName string) error {
|
|||
}
|
||||
|
||||
node.Address = ipaddr
|
||||
node.PullChanges = "yes"
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -500,27 +495,6 @@ func UpdateNetworkNodeAddresses(networkName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// IsNetworkDisplayNameUnique - checks if displayname is unique from other networks
|
||||
func IsNetworkDisplayNameUnique(network *models.Network) (bool, error) {
|
||||
|
||||
isunique := true
|
||||
|
||||
records, err := GetNetworks()
|
||||
|
||||
if err != nil && !database.IsEmptyRecord(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(records); i++ {
|
||||
|
||||
if network.NetID == records[i].DisplayName {
|
||||
isunique = false
|
||||
}
|
||||
}
|
||||
|
||||
return isunique, nil
|
||||
}
|
||||
|
||||
// IsNetworkNameUnique - checks to see if any other networks have the same name (id)
|
||||
func IsNetworkNameUnique(network *models.Network) (bool, error) {
|
||||
|
||||
|
@ -612,14 +586,6 @@ func ValidateNetwork(network *models.Network, isUpdate bool) error {
|
|||
return isFieldUnique && inCharSet
|
||||
})
|
||||
//
|
||||
_ = v.RegisterValidation("displayname_valid", func(fl validator.FieldLevel) bool {
|
||||
isFieldUnique, _ := IsNetworkDisplayNameUnique(network)
|
||||
inCharSet := network.DisplayNameInNetworkCharSet()
|
||||
if isUpdate {
|
||||
return inCharSet
|
||||
}
|
||||
return isFieldUnique && inCharSet
|
||||
})
|
||||
_ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
|
||||
return validation.CheckYesOrNo(fl)
|
||||
})
|
||||
|
|
|
@ -85,7 +85,6 @@ func UncordonNode(nodeid string) (models.Node, error) {
|
|||
}
|
||||
node.SetLastModified()
|
||||
node.IsPending = "no"
|
||||
node.PullChanges = "yes"
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return node, err
|
||||
|
@ -350,13 +349,7 @@ func SetNodeDefaults(node *models.Node) {
|
|||
if node.ListenPort == 0 {
|
||||
node.ListenPort = parentNetwork.DefaultListenPort
|
||||
}
|
||||
if node.SaveConfig == "" {
|
||||
if parentNetwork.DefaultSaveConfig != "" {
|
||||
node.SaveConfig = parentNetwork.DefaultSaveConfig
|
||||
} else {
|
||||
node.SaveConfig = "yes"
|
||||
}
|
||||
}
|
||||
|
||||
if node.Interface == "" {
|
||||
node.Interface = parentNetwork.DefaultInterface
|
||||
}
|
||||
|
@ -396,8 +389,6 @@ func SetNodeDefaults(node *models.Node) {
|
|||
node.SetDefaultName()
|
||||
node.SetLastCheckIn()
|
||||
node.SetLastPeerUpdate()
|
||||
//node.SetRoamingDefault()
|
||||
node.SetPullChangesDefault()
|
||||
node.SetDefaultAction()
|
||||
node.SetIsServerDefault()
|
||||
node.SetIsStaticDefault()
|
||||
|
@ -409,7 +400,7 @@ func SetNodeDefaults(node *models.Node) {
|
|||
node.SetDefaultIsRelay()
|
||||
node.SetDefaultIsDocker()
|
||||
node.SetDefaultIsK8S()
|
||||
node.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
node.SetDefaultIsHub()
|
||||
}
|
||||
|
||||
// GetRecordKey - get record key
|
||||
|
@ -512,32 +503,6 @@ func GetNodeRelay(network string, relayedNodeAddr string) (models.Node, error) {
|
|||
return relay, errors.New(RELAY_NODE_ERR + " " + relayedNodeAddr)
|
||||
}
|
||||
|
||||
// GetNodeByIDorMacAddress - gets the node, if a mac address exists, but not id, then it should delete it and recreate in DB with new ID
|
||||
/*
|
||||
func GetNodeByIDorMacAddress(uuid string, macaddress string, network string) (models.Node, error) {
|
||||
var node models.Node
|
||||
var err error
|
||||
node, err = GetNodeByID(uuid)
|
||||
if err != nil && macaddress != "" && network != "" {
|
||||
node, err = GetNodeByMacAddress(network, macaddress)
|
||||
if err != nil {
|
||||
return models.Node{}, err
|
||||
}
|
||||
err = DeleteNodeByMacAddress(&node, true) // remove node
|
||||
if err != nil {
|
||||
return models.Node{}, err
|
||||
}
|
||||
err = CreateNode(&node)
|
||||
if err != nil {
|
||||
return models.Node{}, err
|
||||
}
|
||||
logger.Log(2, "rewriting legacy node data; node now has id,", node.ID)
|
||||
node.PullChanges = "yes"
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
*/
|
||||
// GetNodeByID - get node by uuid, should have been set by create
|
||||
func GetNodeByID(uuid string) (models.Node, error) {
|
||||
var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,7 +30,6 @@ func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error)
|
|||
node.RelayAddrs = relay.RelayAddrs
|
||||
|
||||
node.SetLastModified()
|
||||
node.PullChanges = "yes"
|
||||
nodeData, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return returnnodes, node, err
|
||||
|
@ -162,7 +161,6 @@ func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
|
|||
node.IsRelay = "no"
|
||||
node.RelayAddrs = []string{}
|
||||
node.SetLastModified()
|
||||
node.PullChanges = "yes"
|
||||
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
|
|
|
@ -389,7 +389,7 @@ func ServerPull(serverNode *models.Node, ifaceDelta bool) error {
|
|||
}
|
||||
serverNode.OS = runtime.GOOS
|
||||
|
||||
if serverNode.PullChanges == "yes" || ifaceDelta {
|
||||
if ifaceDelta {
|
||||
// check for interface change
|
||||
// checks if address is in use by another interface
|
||||
var oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address)
|
||||
|
@ -399,7 +399,6 @@ func ServerPull(serverNode *models.Node, ifaceDelta bool) error {
|
|||
}
|
||||
logger.Log(1, "removed old interface", oldIfaceName)
|
||||
}
|
||||
serverNode.PullChanges = "no"
|
||||
if err = setWGConfig(serverNode, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
|
|||
newNode.MTU != currentNode.MTU ||
|
||||
newNode.PersistentKeepalive != currentNode.PersistentKeepalive ||
|
||||
newNode.DNSOn != currentNode.DNSOn ||
|
||||
len(newNode.ExcludedAddrs) != len(currentNode.ExcludedAddrs) ||
|
||||
len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
|
@ -12,7 +11,6 @@ import (
|
|||
type Network struct {
|
||||
AddressRange string `json:"addressrange" bson:"addressrange" validate:"required,cidr"`
|
||||
AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"regexp=^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$"`
|
||||
DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,min=1,max=20,displayname_valid"`
|
||||
NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"`
|
||||
NodesLastModified int64 `json:"nodeslastmodified" bson:"nodeslastmodified"`
|
||||
NetworkLastModified int64 `json:"networklastmodified" bson:"networklastmodified"`
|
||||
|
@ -21,24 +19,20 @@ type Network struct {
|
|||
NodeLimit int32 `json:"nodelimit" bson:"nodelimit"`
|
||||
DefaultPostUp string `json:"defaultpostup" bson:"defaultpostup"`
|
||||
DefaultPostDown string `json:"defaultpostdown" bson:"defaultpostdown"`
|
||||
KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
|
||||
DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"`
|
||||
DefaultSaveConfig string `json:"defaultsaveconfig" bson:"defaultsaveconfig" validate:"checkyesorno"`
|
||||
AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"`
|
||||
AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"`
|
||||
IsLocal string `json:"islocal" bson:"islocal" validate:"checkyesorno"`
|
||||
IsDualStack string `json:"isdualstack" bson:"isdualstack" validate:"checkyesorno"`
|
||||
IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
|
||||
IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
|
||||
IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub" validate:"checkyesorno"`
|
||||
IsHubAndSpoke string `json:"ishubandspoke" bson:"ishubandspoke" validate:"checkyesorno"`
|
||||
LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
|
||||
|
||||
// checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL
|
||||
DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
|
||||
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
||||
DefaultExtClientDNS string `json:"defaultextclientdns" bson:"defaultextclientdns"`
|
||||
DefaultMTU int32 `json:"defaultmtu" bson:"defaultmtu"`
|
||||
DefaultServerAddrs []ServerAddr `json:"defaultserveraddrs" bson:"defaultserveraddrs" yaml:"defaultserveraddrs"`
|
||||
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
||||
DefaultExtClientDNS string `json:"defaultextclientdns" bson:"defaultextclientdns"`
|
||||
DefaultMTU int32 `json:"defaultmtu" bson:"defaultmtu"`
|
||||
// consider removing - may be depreciated
|
||||
DefaultServerAddrs []ServerAddr `json:"defaultserveraddrs" bson:"defaultserveraddrs" yaml:"defaultserveraddrs"`
|
||||
}
|
||||
|
||||
// SaveData - sensitive fields of a network that should be kept the same
|
||||
|
@ -46,19 +40,6 @@ type SaveData struct { // put sensitive fields here
|
|||
NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"`
|
||||
}
|
||||
|
||||
// Network.DisplayNameInNetworkCharSet - checks if displayname uses valid characters
|
||||
func (network *Network) DisplayNameInNetworkCharSet() bool {
|
||||
|
||||
charset := "abcdefghijklmnopqrstuvwxyz1234567890-_./;% ^#()!@$*"
|
||||
|
||||
for _, char := range network.DisplayName {
|
||||
if !strings.Contains(charset, strings.ToLower(string(char))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Network.SetNodesLastModified - sets nodes last modified on network, depricated
|
||||
func (network *Network) SetNodesLastModified() {
|
||||
network.NodesLastModified = time.Now().Unix()
|
||||
|
@ -81,11 +62,8 @@ func (network *Network) SetDefaults() {
|
|||
if network.IsLocal == "" {
|
||||
network.IsLocal = "no"
|
||||
}
|
||||
if network.IsGRPCHub == "" {
|
||||
network.IsGRPCHub = "no"
|
||||
}
|
||||
if network.DisplayName == "" {
|
||||
network.DisplayName = network.NetID
|
||||
if network.IsHubAndSpoke == "" {
|
||||
network.IsHubAndSpoke = "no"
|
||||
}
|
||||
if network.DefaultInterface == "" {
|
||||
if len(network.NetID) < 13 {
|
||||
|
@ -100,16 +78,9 @@ func (network *Network) SetDefaults() {
|
|||
if network.NodeLimit == 0 {
|
||||
network.NodeLimit = 999999999
|
||||
}
|
||||
if network.DefaultSaveConfig == "" {
|
||||
network.DefaultSaveConfig = "no"
|
||||
}
|
||||
if network.DefaultKeepalive == 0 {
|
||||
network.DefaultKeepalive = 20
|
||||
}
|
||||
//Check-In Interval for Nodes, In Seconds
|
||||
if network.DefaultCheckInInterval == 0 {
|
||||
network.DefaultCheckInInterval = 30
|
||||
}
|
||||
if network.AllowManualSignUp == "" {
|
||||
network.AllowManualSignUp = "no"
|
||||
}
|
||||
|
|
|
@ -38,17 +38,15 @@ type Node struct {
|
|||
PostDown string `json:"postdown" bson:"postdown" yaml:"postdown"`
|
||||
AllowedIPs []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
|
||||
PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
|
||||
SaveConfig string `json:"saveconfig" bson:"saveconfig" yaml:"saveconfig" validate:"checkyesorno"`
|
||||
IsHub string `json:"ishub" bson:"ishub" yaml:"ishub" validate:"checkyesorno"`
|
||||
AccessKey string `json:"accesskey" bson:"accesskey" yaml:"accesskey"`
|
||||
Interface string `json:"interface" bson:"interface" yaml:"interface"`
|
||||
LastModified int64 `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"`
|
||||
KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp" yaml:"keyupdatetimestamp"`
|
||||
ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
|
||||
LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
|
||||
LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
|
||||
MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"macaddress_unique"`
|
||||
// checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL
|
||||
CheckInInterval int32 `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"`
|
||||
Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`
|
||||
Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"`
|
||||
IsRelayed string `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
|
||||
|
@ -63,20 +61,18 @@ type Node struct {
|
|||
IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
|
||||
IsStatic string `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"`
|
||||
UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
|
||||
PullChanges string `json:"pullchanges" bson:"pullchanges" yaml:"pullchanges" validate:"checkyesorno"`
|
||||
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
|
||||
IsDualStack string `json:"isdualstack" bson:"isdualstack" yaml:"isdualstack" validate:"checkyesorno"`
|
||||
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
|
||||
Action string `json:"action" bson:"action" yaml:"action"`
|
||||
IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
|
||||
LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"`
|
||||
//Roaming string `json:"roaming" bson:"roaming" yaml:"roaming" validate:"checkyesorno"`
|
||||
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
|
||||
OS string `json:"os" bson:"os" yaml:"os"`
|
||||
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
|
||||
Version string `json:"version" bson:"version" yaml:"version"`
|
||||
ExcludedAddrs []string `json:"excludedaddrs" bson:"excludedaddrs" yaml:"excludedaddrs"`
|
||||
TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
|
||||
//PullChanges string `json:"pullchanges" bson:"pullchanges" yaml:"pullchanges" validate:"checkyesorno"`
|
||||
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
|
||||
IsDualStack string `json:"isdualstack" bson:"isdualstack" yaml:"isdualstack" validate:"checkyesorno"`
|
||||
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
|
||||
Action string `json:"action" bson:"action" yaml:"action"`
|
||||
IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
|
||||
LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"`
|
||||
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
|
||||
OS string `json:"os" bson:"os" yaml:"os"`
|
||||
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
|
||||
Version string `json:"version" bson:"version" yaml:"version"`
|
||||
TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
|
||||
}
|
||||
|
||||
// NodesArray - used for node sorting
|
||||
|
@ -118,6 +114,13 @@ func (node *Node) SetDefaultIsRelayed() {
|
|||
}
|
||||
}
|
||||
|
||||
// Node.SetDefaultIsRelayed - set default is relayed
|
||||
func (node *Node) SetDefaultIsHub() {
|
||||
if node.IsHub == "" {
|
||||
node.IsHub = "no"
|
||||
}
|
||||
}
|
||||
|
||||
// Node.SetDefaultIsRelay - set default isrelay
|
||||
func (node *Node) SetDefaultIsRelay() {
|
||||
if node.IsRelay == "" {
|
||||
|
@ -167,13 +170,6 @@ func (node *Node) SetDefaultAction() {
|
|||
// }
|
||||
//}
|
||||
|
||||
// Node.SetPullChangesDefault - sets default pull changes status
|
||||
func (node *Node) SetPullChangesDefault() {
|
||||
if node.PullChanges == "" {
|
||||
node.PullChanges = "no"
|
||||
}
|
||||
}
|
||||
|
||||
// Node.SetIPForwardingDefault - set ip forwarding default
|
||||
func (node *Node) SetIPForwardingDefault() {
|
||||
if node.IPForwarding == "" {
|
||||
|
@ -245,13 +241,6 @@ func (node *Node) SetDefaultName() {
|
|||
}
|
||||
}
|
||||
|
||||
// Node.SetDefaultExcludedAddrs - sets ExcludedAddrs to empty array if nil
|
||||
func (node *Node) SetDefaultExcludedAddrs() {
|
||||
if node.ExcludedAddrs == nil {
|
||||
node.ExcludedAddrs = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Node.Fill - fills other node data into calling node data if not set on calling node
|
||||
func (newNode *Node) Fill(currentNode *Node) {
|
||||
newNode.ID = currentNode.ID
|
||||
|
@ -273,8 +262,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
}
|
||||
if newNode.PublicKey == "" && newNode.IsStatic != "yes" {
|
||||
newNode.PublicKey = currentNode.PublicKey
|
||||
} else {
|
||||
newNode.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
}
|
||||
if newNode.Endpoint == "" && newNode.IsStatic != "yes" {
|
||||
newNode.Endpoint = currentNode.Endpoint
|
||||
|
@ -291,9 +278,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
if newNode.PersistentKeepalive == 0 {
|
||||
newNode.PersistentKeepalive = currentNode.PersistentKeepalive
|
||||
}
|
||||
if newNode.SaveConfig == "" {
|
||||
newNode.SaveConfig = currentNode.SaveConfig
|
||||
}
|
||||
if newNode.AccessKey == "" {
|
||||
newNode.AccessKey = currentNode.AccessKey
|
||||
}
|
||||
|
@ -303,9 +287,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
if newNode.LastModified == 0 {
|
||||
newNode.LastModified = currentNode.LastModified
|
||||
}
|
||||
if newNode.KeyUpdateTimeStamp == 0 {
|
||||
newNode.LastModified = currentNode.LastModified
|
||||
}
|
||||
if newNode.ExpirationDateTime == 0 {
|
||||
newNode.ExpirationDateTime = currentNode.ExpirationDateTime
|
||||
}
|
||||
|
@ -318,9 +299,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
if newNode.MacAddress == "" {
|
||||
newNode.MacAddress = currentNode.MacAddress
|
||||
}
|
||||
if newNode.CheckInInterval == 0 {
|
||||
newNode.CheckInInterval = currentNode.CheckInInterval
|
||||
}
|
||||
if newNode.Password != "" {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(newNode.Password), []byte(currentNode.Password))
|
||||
if err != nil && currentNode.Password != newNode.Password {
|
||||
|
@ -354,7 +332,7 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
newNode.IsStatic = currentNode.IsStatic
|
||||
}
|
||||
if newNode.UDPHolePunch == "" {
|
||||
newNode.UDPHolePunch = currentNode.SaveConfig
|
||||
newNode.UDPHolePunch = currentNode.UDPHolePunch
|
||||
}
|
||||
if newNode.DNSOn == "" {
|
||||
newNode.DNSOn = currentNode.DNSOn
|
||||
|
@ -368,9 +346,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
if newNode.IPForwarding == "" {
|
||||
newNode.IPForwarding = currentNode.IPForwarding
|
||||
}
|
||||
if newNode.PullChanges == "" {
|
||||
newNode.PullChanges = currentNode.PullChanges
|
||||
}
|
||||
//if newNode.Roaming == "" {
|
||||
//newNode.Roaming = currentNode.Roaming
|
||||
//}
|
||||
|
@ -407,9 +382,6 @@ func (newNode *Node) Fill(currentNode *Node) {
|
|||
if newNode.Version == "" {
|
||||
newNode.Version = currentNode.Version
|
||||
}
|
||||
if newNode.ExcludedAddrs == nil || len(newNode.ExcludedAddrs) != len(currentNode.ExcludedAddrs) {
|
||||
newNode.ExcludedAddrs = currentNode.ExcludedAddrs
|
||||
}
|
||||
}
|
||||
|
||||
// StringWithCharset - returns random string inside defined charset
|
||||
|
|
|
@ -47,36 +47,6 @@ func GetCommands(cliFlags []cli.Flag) []*cli.Command {
|
|||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "checkin",
|
||||
Usage: "Checks for local changes and then checks into the specified Netmaker network to ask about remote changes.",
|
||||
Flags: cliFlags,
|
||||
// the action, or code that will be executed when
|
||||
// we execute our `ns` command
|
||||
Action: func(c *cli.Context) error {
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = command.CheckIn(cfg)
|
||||
return err
|
||||
},
|
||||
},
|
||||
// {
|
||||
// Name: "push",
|
||||
// Usage: "Push configuration changes to server.",
|
||||
// Flags: cliFlags,
|
||||
// // the action, or code that will be executed when
|
||||
// // we execute our `ns` command
|
||||
// Action: func(c *cli.Context) error {
|
||||
// cfg, _, err := config.GetCLIConfig(c)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// err = command.Push(cfg)
|
||||
// return err
|
||||
// },
|
||||
// },
|
||||
{
|
||||
Name: "pull",
|
||||
Usage: "Pull latest configuration and peers from server.",
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/daemon"
|
||||
|
@ -75,71 +73,6 @@ func getWindowsInterval() int {
|
|||
return interval
|
||||
}
|
||||
|
||||
// RunUserspaceDaemon - runs continual checkins
|
||||
func RunUserspaceDaemon() {
|
||||
|
||||
cfg := config.ClientConfig{
|
||||
Network: "all",
|
||||
}
|
||||
interval := getWindowsInterval()
|
||||
dur := time.Duration(interval) * time.Second
|
||||
for {
|
||||
CheckIn(cfg)
|
||||
time.Sleep(dur)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckIn - runs checkin command from cli
|
||||
func CheckIn(cfg config.ClientConfig) error {
|
||||
//log.Println("checkin --- diabled for now")
|
||||
//return nil
|
||||
var err error
|
||||
var errN error
|
||||
if cfg.Network == "" {
|
||||
ncutils.PrintLog("required, '-n', exiting", 0)
|
||||
os.Exit(1)
|
||||
} else if cfg.Network == "all" {
|
||||
ncutils.PrintLog("running checkin for all networks", 1)
|
||||
networks, err := ncutils.GetSystemNetworks()
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error retrieving networks, exiting", 1)
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
currConf, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
err = functions.CheckConfig(*currConf)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "could not find iface") {
|
||||
err = Pull(cfg)
|
||||
if err != nil {
|
||||
ncutils.PrintLog(err.Error(), 1)
|
||||
}
|
||||
} else {
|
||||
ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
|
||||
}
|
||||
} else {
|
||||
ncutils.PrintLog("checked in successfully for "+network, 1)
|
||||
}
|
||||
}
|
||||
if len(networks) == 0 {
|
||||
if ncutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
|
||||
daemon.StopWindowsDaemon()
|
||||
}
|
||||
}
|
||||
errN = err
|
||||
err = nil
|
||||
} else {
|
||||
err = functions.CheckConfig(cfg)
|
||||
}
|
||||
if err == nil && errN != nil {
|
||||
err = errN
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Leave - runs the leave command from cli
|
||||
func Leave(cfg config.ClientConfig) error {
|
||||
err := functions.LeaveNetwork(cfg.Network)
|
||||
|
@ -151,37 +84,6 @@ func Leave(cfg config.ClientConfig) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Push - runs push command
|
||||
func Push(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
if cfg.Network == "all" || ncutils.IsWindows() {
|
||||
ncutils.PrintLog("pushing config to server for all networks.", 0)
|
||||
networks, err := ncutils.GetSystemNetworks()
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error retrieving networks, exiting.", 0)
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
err = functions.Push(network)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error pushing network configs for network: "+network+"\n"+err.Error(), 1)
|
||||
} else {
|
||||
ncutils.PrintLog("pushed network config for "+network, 1)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
err = functions.Push(cfg.Network)
|
||||
}
|
||||
if err == nil {
|
||||
ncutils.PrintLog("completed pushing network configs to remote server", 1)
|
||||
ncutils.PrintLog("success", 1)
|
||||
} else {
|
||||
ncutils.PrintLog("error occurred pushing configs", 1)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Pull - runs pull command from cli
|
||||
func Pull(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
|
|
|
@ -1,320 +0,0 @@
|
|||
package functions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
func isDeleteError(err error) bool {
|
||||
return err != nil && strings.Contains(err.Error(), models.NODE_DELETE)
|
||||
}
|
||||
|
||||
func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.ClientConfig, network string) bool {
|
||||
ipchange := false
|
||||
var err error
|
||||
if node.IsStatic != "yes" {
|
||||
if node.IsLocal == "no" {
|
||||
extIP, err := ncutils.GetPublicIP()
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error encountered checking public ip addresses: "+err.Error(), 1)
|
||||
}
|
||||
if node.Endpoint != extIP && extIP != "" {
|
||||
ncutils.PrintLog("endpoint has changed from "+
|
||||
node.Endpoint+" to "+extIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.Endpoint = extIP
|
||||
ipchange = true
|
||||
}
|
||||
intIP, err := getPrivateAddr()
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error encountered checking private ip addresses: "+err.Error(), 1)
|
||||
}
|
||||
if node.LocalAddress != intIP && intIP != "" {
|
||||
ncutils.PrintLog("local Address has changed from "+
|
||||
node.LocalAddress+" to "+intIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.LocalAddress = intIP
|
||||
ipchange = true
|
||||
}
|
||||
} else if node.IsLocal == "yes" && node.LocalRange != "" {
|
||||
localIP, err := ncutils.GetLocalIP(node.LocalRange)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error encountered checking local ip addresses: "+err.Error(), 1)
|
||||
}
|
||||
if node.Endpoint != localIP && localIP != "" {
|
||||
ncutils.PrintLog("endpoint has changed from "+
|
||||
node.Endpoint+" to "+localIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.Endpoint = localIP
|
||||
node.LocalAddress = localIP
|
||||
ipchange = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if ipchange {
|
||||
err = config.ModConfig(node)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error modifying config file: "+err.Error(), 1)
|
||||
return false
|
||||
}
|
||||
err = wireguard.SetWGConfig(network, false)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error setting wireguard config: "+err.Error(), 1)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return ipchange && err == nil
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
// func setDNS(node *models.Node, servercfg config.ServerConfig, nodecfg *models.Node) {
|
||||
// if nodecfg.DNSOn == "yes" {
|
||||
// ifacename := node.Interface
|
||||
// nameserver := servercfg.CoreDNSAddr
|
||||
// network := node.Network
|
||||
// local.UpdateDNS(ifacename, network, nameserver)
|
||||
// }
|
||||
// }
|
||||
|
||||
func checkNodeActions(node *models.Node, networkName string, servercfg config.ServerConfig, localNode *models.Node, cfg *config.ClientConfig) string {
|
||||
if (node.Action == models.NODE_UPDATE_KEY || localNode.Action == models.NODE_UPDATE_KEY) &&
|
||||
node.IsStatic != "yes" {
|
||||
err := wireguard.SetWGKeyConfig(networkName, servercfg.GRPCAddress)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("unable to process reset keys request: "+err.Error(), 1)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE {
|
||||
err := RemoveLocalInstance(cfg, networkName)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("error deleting locally: "+err.Error(), 1)
|
||||
}
|
||||
return models.NODE_DELETE
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// CheckConfig - checks if current config of client needs update, see flow below
|
||||
/**
|
||||
* Pull changes if any (interface refresh)
|
||||
* - Save it
|
||||
* Check local changes for (ipAddress, publickey, configfile changes) (interface refresh)
|
||||
* - Save it
|
||||
* - Push it
|
||||
* Pull Peers (sync)
|
||||
*/
|
||||
func CheckConfig(cliconf config.ClientConfig) error {
|
||||
|
||||
network := cliconf.Network
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
currentNode := cfg.Node
|
||||
|
||||
newNode, err := Pull(network, false)
|
||||
if isDeleteError(err) {
|
||||
return RemoveLocalInstance(cfg, network)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newNode.IsPending == "yes" {
|
||||
return errors.New("node is pending")
|
||||
}
|
||||
actionCompleted := checkNodeActions(newNode, network, servercfg, ¤tNode, cfg)
|
||||
if actionCompleted == models.NODE_DELETE {
|
||||
return errors.New("node has been removed")
|
||||
}
|
||||
// Check if ip changed and push if so
|
||||
checkIP(newNode, servercfg, cliconf, network)
|
||||
return Push(network)
|
||||
}
|
||||
|
||||
// Pull - pulls the latest config from the server, if manual it will overwrite
|
||||
func Pull(network string, manual bool) (*models.Node, error) {
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node := cfg.Node
|
||||
//servercfg := cfg.Server
|
||||
|
||||
if cfg.Node.IPForwarding == "yes" && !ncutils.IsWindows() {
|
||||
if err = local.SetIPForwarding(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var resNode models.Node // just need to fill this with either server calls or client calls
|
||||
|
||||
var header metadata.MD
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var ctx context.Context
|
||||
|
||||
if cfg.Node.IsServer != "yes" {
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Failed to authenticate: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Failed to parse node config: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &nodepb.Object{
|
||||
Data: string(data),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}
|
||||
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// ensure that the OS never changes
|
||||
resNode.OS = runtime.GOOS
|
||||
if resNode.PullChanges == "yes" || manual {
|
||||
// check for interface change
|
||||
if cfg.Node.Interface != resNode.Interface {
|
||||
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
|
||||
ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface, 1)
|
||||
}
|
||||
}
|
||||
resNode.PullChanges = "no"
|
||||
if err = config.ModConfig(&resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = wireguard.SetWGConfig(network, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodeData, err := json.Marshal(&resNode)
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
|
||||
if resNode.IsServer != "yes" {
|
||||
if wcclient == nil || ctx == nil {
|
||||
return &cfg.Node, errors.New("issue initializing gRPC client")
|
||||
}
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
Metadata: "",
|
||||
}
|
||||
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err = wireguard.SetWGConfig(network, true); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) && !ncutils.IsFreeBSD() {
|
||||
return Pull(network, true)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
var bkupErr = config.SaveBackup(network)
|
||||
if bkupErr != nil {
|
||||
ncutils.Log("unable to update backup file")
|
||||
}
|
||||
|
||||
return &resNode, err
|
||||
}
|
||||
|
||||
// Push - pushes current client configuration to server
|
||||
func Push(network string) error {
|
||||
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
postnode := cfg.Node
|
||||
// always set the OS on client
|
||||
postnode.OS = runtime.GOOS
|
||||
postnode.SetLastCheckIn()
|
||||
|
||||
var header metadata.MD
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Failed to authenticate with server: "+err.Error(), 1)
|
||||
return err
|
||||
}
|
||||
if postnode.IsPending != "yes" {
|
||||
privateKey, err := wireguard.RetrievePrivKey(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privateKeyWG, err := wgtypes.ParseKey(privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if postnode.PublicKey != privateKeyWG.PublicKey().String() {
|
||||
postnode.PublicKey = privateKeyWG.PublicKey().String()
|
||||
}
|
||||
}
|
||||
nodeData, err := json.Marshal(&postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
Metadata: "",
|
||||
}
|
||||
data, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal([]byte(data.Data), &postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = config.ModConfig(&postnode)
|
||||
return err
|
||||
}
|
|
@ -317,58 +317,3 @@ func WipeLocal(network string) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getLocalIP(node models.Node) string {
|
||||
|
||||
var local string
|
||||
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return local
|
||||
}
|
||||
_, localrange, err := net.ParseCIDR(node.LocalRange)
|
||||
if err != nil {
|
||||
return local
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, i := range ifaces {
|
||||
if i.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
}
|
||||
if i.Flags&net.FlagLoopback != 0 {
|
||||
continue // loopback interface
|
||||
}
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return local
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
if node.IsLocal == "yes" {
|
||||
found = localrange.Contains(ip)
|
||||
} else {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
if node.IsLocal == "yes" {
|
||||
found = localrange.Contains(ip)
|
||||
|
||||
} else {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return local
|
||||
}
|
||||
|
|
|
@ -150,7 +150,6 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
|
|||
ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface+": "+err.Error(), 1)
|
||||
}
|
||||
}
|
||||
newNode.PullChanges = "no"
|
||||
//ensure that OS never changes
|
||||
newNode.OS = runtime.GOOS
|
||||
// check if interface needs to delta
|
||||
|
|
|
@ -144,7 +144,6 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||
DNSOn: cfg.Node.DNSOn,
|
||||
Name: cfg.Node.Name,
|
||||
Endpoint: cfg.Node.Endpoint,
|
||||
SaveConfig: cfg.Node.SaveConfig,
|
||||
UDPHolePunch: cfg.Node.UDPHolePunch,
|
||||
TrafficKeys: cfg.Node.TrafficKeys,
|
||||
OS: runtime.GOOS,
|
||||
|
|
126
netclient/functions/pull.go
Normal file
126
netclient/functions/pull.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
package functions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
// Pull - pulls the latest config from the server, if manual it will overwrite
|
||||
func Pull(network string, manual bool) (*models.Node, error) {
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node := cfg.Node
|
||||
//servercfg := cfg.Server
|
||||
|
||||
if cfg.Node.IPForwarding == "yes" && !ncutils.IsWindows() {
|
||||
if err = local.SetIPForwarding(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var resNode models.Node // just need to fill this with either server calls or client calls
|
||||
|
||||
var header metadata.MD
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var ctx context.Context
|
||||
|
||||
if cfg.Node.IsServer != "yes" {
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Failed to authenticate: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("Failed to parse node config: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &nodepb.Object{
|
||||
Data: string(data),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}
|
||||
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// ensure that the OS never changes
|
||||
resNode.OS = runtime.GOOS
|
||||
if manual {
|
||||
// check for interface change
|
||||
if cfg.Node.Interface != resNode.Interface {
|
||||
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
|
||||
ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface, 1)
|
||||
}
|
||||
}
|
||||
if err = config.ModConfig(&resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = wireguard.SetWGConfig(network, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodeData, err := json.Marshal(&resNode)
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
|
||||
if resNode.IsServer != "yes" {
|
||||
if wcclient == nil || ctx == nil {
|
||||
return &cfg.Node, errors.New("issue initializing gRPC client")
|
||||
}
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
Metadata: "",
|
||||
}
|
||||
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err = wireguard.SetWGConfig(network, true); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) && !ncutils.IsFreeBSD() {
|
||||
return Pull(network, true)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
var bkupErr = config.SaveBackup(network)
|
||||
if bkupErr != nil {
|
||||
ncutils.Log("unable to update backup file")
|
||||
}
|
||||
|
||||
return &resNode, err
|
||||
}
|
|
@ -22,7 +22,6 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
|
|||
newNode.IsPending != currentNode.IsPending ||
|
||||
newNode.PersistentKeepalive != currentNode.PersistentKeepalive ||
|
||||
newNode.DNSOn != currentNode.DNSOn ||
|
||||
len(newNode.ExcludedAddrs) != len(currentNode.ExcludedAddrs) ||
|
||||
len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) {
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue