Merge pull request #793 from gravitl/feature_v0.11.0_commsnet

Feature v0.11.0 commsnet
This commit is contained in:
Alex Feiszli 2022-02-18 10:18:00 -05:00 committed by GitHub
commit 0b1bf1b9aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 161 additions and 747 deletions

View file

@ -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

View file

@ -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)

View file

@ -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) {

View file

@ -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 {

View file

@ -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 {

View file

@ -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)
})

View file

@ -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 {

View file

@ -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 {

View file

@ -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
}

View file

@ -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
}

View file

@ -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"
}

View file

@ -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

View file

@ -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.",

View file

@ -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

View file

@ -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, &currentNode, 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
}

View file

@ -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
}

View file

@ -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

View file

@ -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
View 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
}

View file

@ -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
}