fixing merge conflict

This commit is contained in:
afeiszli 2023-02-16 23:37:02 -05:00
commit 5d42face10
30 changed files with 746 additions and 363 deletions

View file

@ -49,6 +49,7 @@ jobs:
go-version: 1.19
- name: run tests
run: |
go vet ./...
go test -p 1 ./... -v
env:
DATABASE: sqlite

View file

@ -0,0 +1,20 @@
package host
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var addHostNetworkCmd = &cobra.Command{
Use: "add_network HostID Network",
Args: cobra.ExactArgs(2),
Short: "Add a network to a host",
Long: `Add a network to a host`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.AddHostToNetwork(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(addHostNetworkCmd)
}

View file

@ -0,0 +1,20 @@
package host
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var deleteHostNetworkCmd = &cobra.Command{
Use: "delete_network HostID Network",
Args: cobra.ExactArgs(2),
Short: "Delete a network from a host",
Long: `Delete a network from a host`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.DeleteHostFromNetwork(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(deleteHostNetworkCmd)
}

View file

@ -1,22 +0,0 @@
package host
import (
"strings"
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var hostUpdateNetworksCmd = &cobra.Command{
Use: "update_network HostID Networks(comma separated list)",
Args: cobra.ExactArgs(2),
Short: "Update a host's networks",
Long: `Update a host's networks`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.UpdateHostNetworks(args[0], strings.Split(args[1], ",")))
},
}
func init() {
rootCmd.AddCommand(hostUpdateNetworksCmd)
}

View file

@ -26,11 +26,14 @@ func UpdateHost(hostID string, body *models.ApiHost) *models.ApiHost {
return request[models.ApiHost](http.MethodPut, "/api/hosts/"+hostID, body)
}
// UpdateHostNetworks - update a host's networks
func UpdateHostNetworks(hostID string, networks []string) *hostNetworksUpdatePayload {
return request[hostNetworksUpdatePayload](http.MethodPut, "/api/hosts/"+hostID+"/networks", &hostNetworksUpdatePayload{
Networks: networks,
})
// AddHostToNetwork - add a network to host
func AddHostToNetwork(hostID, network string) *hostNetworksUpdatePayload {
return request[hostNetworksUpdatePayload](http.MethodPost, "/api/hosts/"+hostID+"/networks/"+network, nil)
}
// DeleteHostFromNetwork - deletes a network from host
func DeleteHostFromNetwork(hostID, network string) *hostNetworksUpdatePayload {
return request[hostNetworksUpdatePayload](http.MethodDelete, "/api/hosts/"+hostID+"/networks/"+network, nil)
}
// CreateRelay - turn a host into a relay

View file

@ -176,9 +176,14 @@ func createDNS(w http.ResponseWriter, r *http.Request) {
}
logger.Log(1, "new DNS record added:", entry.Name)
if servercfg.IsMessageQueueBackend() {
if err = mq.PublishPeerUpdate(); err != nil {
logger.Log(0, "failed to publish peer update after ACL update on", entry.Network)
}
go func() {
if err = mq.PublishPeerUpdate(); err != nil {
logger.Log(0, "failed to publish peer update after ACL update on", entry.Network)
}
if err := mq.PublishCustomDNS(&entry); err != nil {
logger.Log(0, "error publishing custom dns", err.Error())
}
}()
}
logger.Log(2, r.Header.Get("user"),
fmt.Sprintf("DNS entry is set: %+v", entry))
@ -221,6 +226,16 @@ func deleteDNS(w http.ResponseWriter, r *http.Request) {
return
}
json.NewEncoder(w).Encode(entrytext + " deleted.")
go func() {
dns := models.DNSUpdate{
Action: models.DNSDeleteByName,
Name: entrytext,
}
if err := mq.PublishDNSUpdate(params["network"], dns); err != nil {
logger.Log(0, "failed to publish dns update", err.Error())
}
}()
}
// GetDNSEntry - gets a DNS entry

View file

@ -6,17 +6,16 @@ import (
"testing"
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
)
var dnsHost models.Host
func TestGetAllDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
@ -28,7 +27,7 @@ func TestGetAllDNS(t *testing.T) {
})
t.Run("OneEntry", func(t *testing.T) {
entry := models.DNSEntry{
"10.0.0.3", "", "newhost", "skynet",
Address: "10.0.0.3", Name: "newhost", Network: "skynet",
}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
@ -37,7 +36,7 @@ func TestGetAllDNS(t *testing.T) {
assert.Equal(t, 1, len(entries))
})
t.Run("MultipleEntry", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.7", "", "anotherhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.7", Name: "anotherhost", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
entries, err := logic.GetAllDNS()
@ -47,7 +46,6 @@ func TestGetAllDNS(t *testing.T) {
}
func TestGetNodeDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
@ -94,7 +92,6 @@ func TestGetNodeDNS(t *testing.T) {
})
}
func TestGetCustomDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
t.Run("NoNetworks", func(t *testing.T) {
@ -115,7 +112,7 @@ func TestGetCustomDNS(t *testing.T) {
assert.Equal(t, 0, len(dns))
})
t.Run("EntryExist", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.3", "", "custom1", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.3", Name: "custom1", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
dns, err := logic.GetCustomDNS("skynet")
@ -123,7 +120,7 @@ func TestGetCustomDNS(t *testing.T) {
assert.Equal(t, 1, len(dns))
})
t.Run("MultipleEntries", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.4", "", "host4", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.4", Name: "host4", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
dns, err := logic.GetCustomDNS("skynet")
@ -133,7 +130,6 @@ func TestGetCustomDNS(t *testing.T) {
}
func TestGetDNSEntryNum(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
@ -143,7 +139,7 @@ func TestGetDNSEntryNum(t *testing.T) {
assert.Equal(t, 0, num)
})
t.Run("NodeExists", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
num, err := logic.GetDNSEntryNum("newhost", "skynet")
@ -152,7 +148,6 @@ func TestGetDNSEntryNum(t *testing.T) {
})
}
func TestGetDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
@ -162,7 +157,7 @@ func TestGetDNS(t *testing.T) {
assert.Nil(t, dns)
})
t.Run("CustomDNSExists", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
dns, err := logic.GetDNS("skynet")
@ -182,7 +177,7 @@ func TestGetDNS(t *testing.T) {
assert.Equal(t, 1, len(dns))
})
t.Run("NodeAndCustomDNS", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
dns, err := logic.GetDNS("skynet")
@ -196,18 +191,16 @@ func TestGetDNS(t *testing.T) {
}
func TestCreateDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
dns, err := logic.CreateDNS(entry)
assert.Nil(t, err)
assert.Equal(t, "newhost", dns.Name)
}
func TestSetDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
t.Run("NoNetworks", func(t *testing.T) {
@ -239,7 +232,7 @@ func TestSetDNS(t *testing.T) {
assert.Contains(t, string(content), "linuxhost.skynet")
})
t.Run("EntryExists", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.3", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.3", Name: "newhost", Network: "skynet"}
_, err := logic.CreateDNS(entry)
assert.Nil(t, err)
err = logic.SetDNS()
@ -255,12 +248,11 @@ func TestSetDNS(t *testing.T) {
}
func TestGetDNSEntry(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
createTestNode()
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
_, _ = logic.CreateDNS(entry)
t.Run("wrong net", func(t *testing.T) {
entry, err := GetDNSEntry("newhost", "w286 Toronto Street South, Uxbridge, ONirecat")
@ -285,11 +277,10 @@ func TestGetDNSEntry(t *testing.T) {
}
func TestDeleteDNS(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
_, _ = logic.CreateDNS(entry)
t.Run("EntryExists", func(t *testing.T) {
err := logic.DeleteDNS("newhost", "skynet")
@ -307,20 +298,19 @@ func TestDeleteDNS(t *testing.T) {
}
func TestValidateDNSUpdate(t *testing.T) {
database.InitializeDatabase()
deleteAllDNS(t)
deleteAllNetworks()
createNet()
entry := models.DNSEntry{"10.0.0.2", "", "myhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "skynet"}
t.Run("BadNetwork", func(t *testing.T) {
change := models.DNSEntry{"10.0.0.2", "", "myhost", "badnet"}
change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "badnet"}
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
})
t.Run("EmptyNetwork", func(t *testing.T) {
//this can't actually happen as change.Network is populated if is blank
change := models.DNSEntry{"10.0.0.2", "", "myhost", ""}
// this can't actually happen as change.Network is populated if is blank
change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost"}
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
@ -333,14 +323,14 @@ func TestValidateDNSUpdate(t *testing.T) {
// assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
// })
t.Run("BadAddress", func(t *testing.T) {
change := models.DNSEntry{"10.0.256.1", "", "myhost", "skynet"}
change := models.DNSEntry{Address: "10.0.256.1", Name: "myhost", Network: "skynet"}
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
})
t.Run("EmptyName", func(t *testing.T) {
//this can't actually happen as change.Name is populated if is blank
change := models.DNSEntry{"10.0.0.2", "", "", "skynet"}
// this can't actually happen as change.Name is populated if is blank
change := models.DNSEntry{Address: "10.0.0.2", Network: "skynet"}
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
@ -350,29 +340,28 @@ func TestValidateDNSUpdate(t *testing.T) {
for i := 1; i < 194; i++ {
name = name + "a"
}
change := models.DNSEntry{"10.0.0.2", "", name, "skynet"}
change := models.DNSEntry{Address: "10.0.0.2", Name: name, Network: "skynet"}
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
})
t.Run("NameUnique", func(t *testing.T) {
change := models.DNSEntry{"10.0.0.2", "", "myhost", "wirecat"}
change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "wirecat"}
_, _ = logic.CreateDNS(entry)
_, _ = logic.CreateDNS(change)
err := logic.ValidateDNSUpdate(change, entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'name_unique' tag")
//cleanup
// cleanup
err = logic.DeleteDNS("myhost", "wirecat")
assert.Nil(t, err)
})
}
func TestValidateDNSCreate(t *testing.T) {
database.InitializeDatabase()
_ = logic.DeleteDNS("mynode", "skynet")
t.Run("NoNetwork", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "myhost", "badnet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "badnet"}
err := logic.ValidateDNSCreate(entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
@ -384,13 +373,13 @@ func TestValidateDNSCreate(t *testing.T) {
// assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
// })
t.Run("BadAddress", func(t *testing.T) {
entry := models.DNSEntry{"10.0.256.1", "", "myhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.256.1", Name: "myhost", Network: "skynet"}
err := logic.ValidateDNSCreate(entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
})
t.Run("EmptyName", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Network: "skynet"}
err := logic.ValidateDNSCreate(entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
@ -400,13 +389,13 @@ func TestValidateDNSCreate(t *testing.T) {
for i := 1; i < 194; i++ {
name = name + "a"
}
entry := models.DNSEntry{"10.0.0.2", "", name, "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: name, Network: "skynet"}
err := logic.ValidateDNSCreate(entry)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
})
t.Run("NameUnique", func(t *testing.T) {
entry := models.DNSEntry{"10.0.0.2", "", "myhost", "skynet"}
entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "skynet"}
_, _ = logic.CreateDNS(entry)
err := logic.ValidateDNSCreate(entry)
assert.NotNil(t, err)

View file

@ -388,10 +388,15 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
logger.Log(0, r.Header.Get("user"), "created new ext client on network", networkName)
w.WriteHeader(http.StatusOK)
err = mq.PublishExtPeerUpdate(&node)
if err != nil {
logger.Log(1, "error setting ext peers on "+nodeid+": "+err.Error())
}
go func() {
err = mq.PublishExtPeerUpdate(&node)
if err != nil {
logger.Log(1, "error setting ext peers on "+nodeid+": "+err.Error())
}
if err := mq.PublishExtCLientDNS(&extclient); err != nil {
logger.Log(1, "error publishing extclient dns", err.Error())
}
}()
}
// swagger:route PUT /api/extclients/{network}/{clientid} ext_client updateExtClient
@ -459,7 +464,6 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
return
}
}
if changedID && oldExtClient.OwnerID != "" {
if err := pro.DissociateNetworkUserClient(oldExtClient.OwnerID, networkName, oldExtClient.ClientID); err != nil {
logger.Log(0, "failed to dissociate client", oldExtClient.ClientID, "from user", oldExtClient.OwnerID)
@ -471,7 +475,8 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
// == END PRO ==
var changedEnabled = newExtClient.Enabled != oldExtClient.Enabled // indicates there was a change in enablement
// extra var need as logic.Update changes oldExtClient
currentClient := oldExtClient
newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], newExtClient.Enabled, &oldExtClient)
if err != nil {
logger.Log(0, r.Header.Get("user"),
@ -490,6 +495,13 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(newclient)
if changedID {
go func() {
if err := mq.PublishExtClientDNSUpdate(currentClient, newExtClient, networkName); err != nil {
logger.Log(1, "error pubishing dns update for extcient update", err.Error())
}
}()
}
}
// swagger:route DELETE /api/extclients/{network}/{clientid} ext_client deleteExtClient
@ -554,10 +566,15 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) {
return
}
err = mq.PublishExtPeerUpdate(&ingressnode)
if err != nil {
logger.Log(1, "error setting ext peers on "+ingressnode.ID.String()+": "+err.Error())
}
go func() {
err = mq.PublishExtPeerUpdate(&ingressnode)
if err != nil {
logger.Log(1, "error setting ext peers on "+ingressnode.ID.String()+": "+err.Error())
}
if err := mq.PublishDeleteExtClientDNS(&extclient); err != nil {
logger.Log(1, "error publishing dns update for extclient deletion", err.Error())
}
}()
logger.Log(0, r.Header.Get("user"),
"Deleted extclient client", params["clientid"], "from network", params["network"])

View file

@ -108,6 +108,19 @@ func updateHost(w http.ResponseWriter, r *http.Request) {
if err := mq.PublishPeerUpdate(); err != nil {
logger.Log(0, "fail to publish peer update: ", err.Error())
}
if newHost.Name != currHost.Name {
networks := logic.GetHostNetworks(currHost.ID.String())
if err := mq.PublishHostDNSUpdate(currHost, newHost, networks); err != nil {
var dnsError *models.DNSError
if errors.Is(err, dnsError) {
for _, message := range err.(models.DNSError).ErrorStrings {
logger.Log(0, message)
}
} else {
logger.Log(0, err.Error())
}
}
}
}()
apiHostData := newHost.ConvertNMHostToAPI()
@ -268,17 +281,23 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
node.Action = models.NODE_DELETE
node.PendingDelete = true
logger.Log(1, "deleting node", node.ID.String(), "from host", currHost.Name)
if err := logic.DeleteNode(node, false); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete node"), "internal"))
return
}
// notify node change
runUpdates(node, false)
go func() { // notify of peer change
if err := mq.PublishPeerUpdate(); err != nil {
logger.Log(1, "error publishing peer update ", err.Error())
}
if err := mq.PublishDNSDelete(node, currHost); err != nil {
logger.Log(1, "error publishing dns update", err.Error())
}
}()
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("removed host %s from network %s", currHost.Name, network))
w.WriteHeader(http.StatusOK)

View file

@ -1,11 +1,13 @@
package controller
import (
"context"
"os"
"testing"
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
@ -20,8 +22,27 @@ type NetworkValidationTestCase struct {
var netHost models.Host
func TestMain(m *testing.M) {
database.InitializeDatabase()
defer database.CloseDB()
logic.CreateAdmin(&models.User{
UserName: "admin",
Password: "password",
IsAdmin: true,
Networks: []string{},
Groups: []string{},
})
peerUpdate := make(chan *models.Node)
go logic.ManageZombies(context.Background(), peerUpdate)
go func() {
for update := range peerUpdate {
//do nothing
logger.Log(3, "received node update", update.Action)
}
}()
}
func TestCreateNetwork(t *testing.T) {
initialize()
deleteAllNetworks()
var network models.Network
@ -34,7 +55,6 @@ func TestCreateNetwork(t *testing.T) {
assert.Nil(t, err)
}
func TestGetNetwork(t *testing.T) {
initialize()
createNet()
t.Run("GetExistingNetwork", func(t *testing.T) {
@ -50,7 +70,6 @@ func TestGetNetwork(t *testing.T) {
}
func TestDeleteNetwork(t *testing.T) {
initialize()
createNet()
//create nodes
t.Run("NetworkwithNodes", func(t *testing.T) {
@ -66,7 +85,6 @@ func TestDeleteNetwork(t *testing.T) {
}
func TestCreateKey(t *testing.T) {
initialize()
createNet()
keys, _ := logic.GetKeys("skynet")
for _, key := range keys {
@ -138,7 +156,6 @@ func TestCreateKey(t *testing.T) {
}
func TestGetKeys(t *testing.T) {
initialize()
deleteAllNetworks()
createNet()
network, err := logic.GetNetwork("skynet")
@ -161,7 +178,6 @@ func TestGetKeys(t *testing.T) {
})
}
func TestDeleteKey(t *testing.T) {
initialize()
createNet()
network, err := logic.GetNetwork("skynet")
assert.Nil(t, err)
@ -183,7 +199,6 @@ func TestDeleteKey(t *testing.T) {
func TestSecurityCheck(t *testing.T) {
//these seem to work but not sure it the tests are really testing the functionality
initialize()
os.Setenv("MASTER_KEY", "secretkey")
t.Run("NoNetwork", func(t *testing.T) {
networks, username, err := logic.UserPermissions(false, "", "Bearer secretkey")
@ -214,7 +229,6 @@ func TestValidateNetwork(t *testing.T) {
//t.Skip()
//This functions is not called by anyone
//it panics as validation function 'display_name_valid' is not defined
initialize()
//yes := true
//no := false
//deleteNet(t)
@ -291,7 +305,6 @@ func TestValidateNetwork(t *testing.T) {
func TestIpv6Network(t *testing.T) {
//these seem to work but not sure it the tests are really testing the functionality
initialize()
os.Setenv("MASTER_KEY", "secretkey")
deleteAllNetworks()
createNet()
@ -318,21 +331,6 @@ func deleteAllNetworks() {
}
}
func initialize() {
database.InitializeDatabase()
createAdminUser()
}
func createAdminUser() {
logic.CreateAdmin(&models.User{
UserName: "admin",
Password: "password",
IsAdmin: true,
Networks: []string{},
Groups: []string{},
})
}
func createNet() {
var network models.Network
network.NetID = "skynet"

View file

@ -657,6 +657,30 @@ func createNode(w http.ResponseWriter, r *http.Request) {
}
}()
//runForceServerUpdate(&data.Node, true)
go func() {
dns := models.DNSUpdate{
Action: models.DNSInsert,
Name: data.Host.Name + "." + data.Node.Network,
}
if data.Node.Address.IP != nil {
dns.Address = data.Node.Address.IP.String()
//publish new node dns entry to all nodes on network
if err := mq.PublishDNSUpdate(data.Node.Network, dns); err != nil {
logger.Log(1, "failed to publish dns update on node creation", err.Error())
}
}
if data.Node.Address6.IP != nil {
dns.Address = data.Node.Address6.IP.String()
//publish new node dns entry to all nodes on network
if err := mq.PublishDNSUpdate(data.Node.Network, dns); err != nil {
logger.Log(1, "failed to publish dns update on node creation", err.Error())
}
}
//publish add dns records for network to new node
if err := mq.PublishAllDNS(&data.Node); err != nil {
logger.Log(1, "failed to publish dns update on node creation", err.Error())
}
}()
}
// == EGRESS ==
@ -929,6 +953,11 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(apiNode)
runUpdates(newNode, ifaceDelta)
go func() {
if err := mq.PublishReplaceDNS(&currentNode, newNode, host); err != nil {
logger.Log(1, "failed to publish dns update", err.Error())
}
}()
}
// swagger:route DELETE /api/nodes/{network}/{nodeid} nodes deleteNode
@ -976,6 +1005,13 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
if err := mq.PublishPeerUpdate(); err != nil {
logger.Log(1, "error publishing peer update ", err.Error())
}
host, err := logic.GetHost(node.HostID.String())
if err != nil {
logger.Log(1, "failed to retrieve host for node", node.ID.String(), err.Error())
}
if err := mq.PublishDNSDelete(&node, host); err != nil {
logger.Log(1, "error publishing dns update", err.Error())
}
}()
}

View file

@ -21,7 +21,6 @@ func TestCreateEgressGateway(t *testing.T) {
var gateway models.EgressGatewayRequest
gateway.Ranges = []string{"10.100.100.0/24"}
gateway.NetID = "skynet"
database.InitializeDatabase()
deleteAllNetworks()
createNet()
t.Run("NoNodes", func(t *testing.T) {
@ -78,7 +77,6 @@ func TestCreateEgressGateway(t *testing.T) {
}
func TestDeleteEgressGateway(t *testing.T) {
var gateway models.EgressGatewayRequest
database.InitializeDatabase()
deleteAllNetworks()
createNet()
testnode := createTestNode()
@ -110,7 +108,6 @@ func TestDeleteEgressGateway(t *testing.T) {
}
func TestGetNetworkNodes(t *testing.T) {
database.InitializeDatabase()
deleteAllNetworks()
createNet()
t.Run("BadNet", func(t *testing.T) {

View file

@ -3,22 +3,24 @@ package controller
import (
"testing"
"github.com/gravitl/netmaker/database"
"github.com/stretchr/testify/assert"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
)
func deleteAllUsers() {
func deleteAllUsers(t *testing.T) {
t.Helper()
users, _ := logic.GetUsers()
for _, user := range users {
logic.DeleteUser(user.UserName)
if _, err := logic.DeleteUser(user.UserName); err != nil {
t.Fatal(err)
}
}
}
func TestHasAdmin(t *testing.T) {
//delete all current users
database.InitializeDatabase()
// delete all current users
users, _ := logic.GetUsers()
for _, user := range users {
success, err := logic.DeleteUser(user.UserName)
@ -31,7 +33,7 @@ func TestHasAdmin(t *testing.T) {
assert.False(t, found)
})
t.Run("No admin user", func(t *testing.T) {
var user = models.User{"noadmin", "password", nil, false, nil}
var user = models.User{UserName: "noadmin", Password: "password"}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasAdmin()
@ -39,7 +41,7 @@ func TestHasAdmin(t *testing.T) {
assert.False(t, found)
})
t.Run("admin user", func(t *testing.T) {
var user = models.User{"admin", "password", nil, true, nil}
var user = models.User{UserName: "admin", Password: "password", IsAdmin: true}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasAdmin()
@ -47,8 +49,8 @@ func TestHasAdmin(t *testing.T) {
assert.True(t, found)
})
t.Run("multiple admins", func(t *testing.T) {
var user = models.User{"admin1", "password", nil, true, nil}
err := logic.CreateUser(&user)
var user = models.User{UserName: "admin1", Password: "password", IsAdmin: true}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasAdmin()
assert.Nil(t, err)
@ -57,9 +59,8 @@ func TestHasAdmin(t *testing.T) {
}
func TestCreateUser(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
user := models.User{"admin", "password", nil, true, nil}
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", IsAdmin: true}
t.Run("NoUser", func(t *testing.T) {
err := logic.CreateUser(&user)
assert.Nil(t, err)
@ -72,8 +73,7 @@ func TestCreateUser(t *testing.T) {
}
func TestCreateAdmin(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
deleteAllUsers(t)
var user models.User
t.Run("NoAdmin", func(t *testing.T) {
user.UserName = "admin"
@ -90,16 +90,17 @@ func TestCreateAdmin(t *testing.T) {
}
func TestDeleteUser(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
deleteAllUsers(t)
t.Run("NonExistent User", func(t *testing.T) {
deleted, err := logic.DeleteUser("admin")
assert.EqualError(t, err, "user does not exist")
assert.False(t, deleted)
})
t.Run("Existing User", func(t *testing.T) {
user := models.User{"admin", "password", nil, true, nil}
logic.CreateUser(&user)
user := models.User{UserName: "admin", Password: "password", IsAdmin: true}
if err := logic.CreateUser(&user); err != nil {
t.Fatal(err)
}
deleted, err := logic.DeleteUser("admin")
assert.Nil(t, err)
assert.True(t, deleted)
@ -107,7 +108,6 @@ func TestDeleteUser(t *testing.T) {
}
func TestValidateUser(t *testing.T) {
database.InitializeDatabase()
var user models.User
t.Run("Valid Create", func(t *testing.T) {
user.UserName = "admin"
@ -126,21 +126,21 @@ func TestValidateUser(t *testing.T) {
user.UserName = "*invalid"
err := logic.ValidateUser(&user)
assert.Error(t, err)
//assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("Short UserName", func(t *testing.T) {
t.Skip()
user.UserName = "1"
err := logic.ValidateUser(&user)
assert.NotNil(t, err)
//assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("Empty UserName", func(t *testing.T) {
t.Skip()
user.UserName = ""
err := logic.ValidateUser(&user)
assert.EqualError(t, err, "some string")
//assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("EmptyPassword", func(t *testing.T) {
user.Password = ""
@ -155,16 +155,19 @@ func TestValidateUser(t *testing.T) {
}
func TestGetUser(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", Networks: nil, IsAdmin: true, Groups: nil}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.GetUser("admin")
assert.EqualError(t, err, "could not find any records")
assert.Equal(t, "", admin.UserName)
})
t.Run("UserExisits", func(t *testing.T) {
user := models.User{"admin", "password", nil, true, nil}
logic.CreateUser(&user)
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admin, err := logic.GetUser("admin")
assert.Nil(t, err)
assert.Equal(t, user.UserName, admin.UserName)
@ -172,30 +175,36 @@ func TestGetUser(t *testing.T) {
}
func TestGetUsers(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
deleteAllUsers(t)
adminUser := models.User{UserName: "admin", Password: "password", IsAdmin: true}
user := models.User{UserName: "admin", Password: "password", IsAdmin: false}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.GetUsers()
assert.EqualError(t, err, "could not find any records")
assert.Equal(t, []models.ReturnUser(nil), admin)
})
t.Run("UserExisits", func(t *testing.T) {
user := models.User{"admin", "password", nil, true, nil}
logic.CreateUser(&user)
if err := logic.CreateUser(&adminUser); err != nil {
t.Error(err)
}
admins, err := logic.GetUsers()
assert.Nil(t, err)
assert.Equal(t, user.UserName, admins[0].UserName)
assert.Equal(t, adminUser.UserName, admins[0].UserName)
})
t.Run("MulipleUsers", func(t *testing.T) {
user := models.User{"user", "password", nil, true, nil}
logic.CreateUser(&user)
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admins, err := logic.GetUsers()
assert.Nil(t, err)
for _, u := range admins {
if u.UserName == "admin" {
assert.Equal(t, "admin", u.UserName)
assert.Equal(t, true, u.IsAdmin)
} else {
assert.Equal(t, user.UserName, u.UserName)
assert.Equal(t, user.IsAdmin, u.IsAdmin)
}
}
})
@ -203,10 +212,9 @@ func TestGetUsers(t *testing.T) {
}
func TestUpdateUser(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
user := models.User{"admin", "password", nil, true, nil}
newuser := models.User{"hello", "world", []string{"wirecat, netmaker"}, true, []string{}}
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", IsAdmin: true}
newuser := models.User{UserName: "hello", Password: "world", Networks: []string{"wirecat, netmaker"}, IsAdmin: true, Groups: []string{}}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.UpdateUser(&newuser, &user)
assert.EqualError(t, err, "could not find any records")
@ -214,7 +222,9 @@ func TestUpdateUser(t *testing.T) {
})
t.Run("UserExists", func(t *testing.T) {
logic.CreateUser(&user)
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admin, err := logic.UpdateUser(&newuser, &user)
assert.Nil(t, err)
assert.Equal(t, newuser.UserName, admin.UserName)
@ -246,8 +256,8 @@ func TestUpdateUser(t *testing.T) {
// }
func TestVerifyAuthRequest(t *testing.T) {
database.InitializeDatabase()
deleteAllUsers()
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", Networks: nil, IsAdmin: true, Groups: nil}
var authRequest models.UserAuthParams
t.Run("EmptyUserName", func(t *testing.T) {
authRequest.UserName = ""
@ -271,23 +281,26 @@ func TestVerifyAuthRequest(t *testing.T) {
assert.EqualError(t, err, "error retrieving user from db: could not find any records")
})
t.Run("Non-Admin", func(t *testing.T) {
user := models.User{"nonadmin", "somepass", nil, false, []string{}}
logic.CreateUser(&user)
authRequest := models.UserAuthParams{"nonadmin", "somepass"}
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
authRequest := models.UserAuthParams{UserName: "nonadmin", Password: "somepass"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.NotNil(t, jwt)
assert.Nil(t, err)
})
t.Run("WrongPassword", func(t *testing.T) {
user := models.User{"admin", "password", nil, false, []string{}}
logic.CreateUser(&user)
authRequest := models.UserAuthParams{"admin", "badpass"}
user := models.User{UserName: "admin", Password: "password", Groups: []string{}}
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
authRequest := models.UserAuthParams{UserName: "admin", Password: "badpass"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Equal(t, "", jwt)
assert.EqualError(t, err, "incorrect credentials")
})
t.Run("Success", func(t *testing.T) {
authRequest := models.UserAuthParams{"admin", "password"}
authRequest := models.UserAuthParams{UserName: "admin", Password: "password"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Nil(t, err)
assert.NotNil(t, jwt)

View file

@ -1,10 +1,12 @@
package functions
import (
"context"
"encoding/json"
"testing"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
)
@ -19,11 +21,27 @@ var (
}
)
func TestMain(m *testing.M) {
database.InitializeDatabase()
defer database.CloseDB()
logic.CreateAdmin(&models.User{
UserName: "admin",
Password: "password",
IsAdmin: true,
Networks: []string{},
Groups: []string{},
})
peerUpdate := make(chan *models.Node)
go logic.ManageZombies(context.Background(), peerUpdate)
go func() {
for update := range peerUpdate {
//do nothing
logger.Log(3, "received node update", update.Action)
}
}()
}
func TestNetworkExists(t *testing.T) {
err := database.InitializeDatabase()
if err != nil {
t.Fatalf("error initilizing database: %s", err)
}
database.DeleteRecord(database.NETWORKS_TABLE_NAME, testNetwork.NetID)
defer database.CloseDB()
exists, err := logic.NetworkExists(testNetwork.NetID)
@ -53,10 +71,6 @@ func TestNetworkExists(t *testing.T) {
}
func TestGetAllExtClients(t *testing.T) {
err := database.InitializeDatabase()
if err != nil {
t.Fatalf("error initilizing database: %s", err)
}
defer database.CloseDB()
database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, testExternalClient.ClientID)

17
go.mod
View file

@ -4,7 +4,7 @@ go 1.19
require (
github.com/eclipse/paho.mqtt.golang v1.4.2
github.com/go-playground/validator/v10 v10.11.1
github.com/go-playground/validator/v10 v10.11.2
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/google/uuid v1.3.0
github.com/gorilla/handlers v1.5.1
@ -15,11 +15,11 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/stretchr/testify v1.8.1
github.com/txn2/txeh v1.3.0
golang.org/x/crypto v0.3.0
golang.org/x/net v0.4.0 // indirect
golang.org/x/oauth2 v0.3.0
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/crypto v0.6.0
golang.org/x/net v0.6.0 // indirect
golang.org/x/oauth2 v0.4.0
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c // indirect
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220324164955-056925b7df31
google.golang.org/protobuf v1.28.1 // indirect
@ -29,7 +29,6 @@ require (
require (
filippo.io/edwards25519 v1.0.0
github.com/c-robinson/iplib v1.0.6
github.com/go-ping/ping v1.1.0
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0
)
@ -60,8 +59,8 @@ require (
cloud.google.com/go/compute v1.12.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/hashicorp/go-version v1.6.0

50
go.sum
View file

@ -17,7 +17,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -29,16 +28,13 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -52,7 +48,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
@ -73,13 +68,10 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
@ -106,7 +98,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -116,9 +107,7 @@ github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sA
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f h1:BSnJgAfHzEp7o8PYJ7YfwAVHhqu7BYUTggcn/LGlUWY=
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f/go.mod h1:UW/gxgQwSePTvL1KA8QEHsXeYHP4xkoXgbDdN781p34=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@ -160,10 +149,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -172,17 +160,18 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -193,10 +182,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -205,8 +192,9 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
@ -215,8 +203,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@ -240,11 +229,8 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gortc.io/stun v1.23.0 h1:CpRQFjakCZMwVKTwInKbcCzlBklj62LGzD3NPdFyGrE=

View file

@ -1,17 +1,38 @@
package logic
import (
"context"
"net"
"testing"
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/matryer/is"
)
func TestCheckPorts(t *testing.T) {
func TestMain(m *testing.M) {
database.InitializeDatabase()
defer database.CloseDB()
CreateAdmin(&models.User{
UserName: "admin",
Password: "password",
IsAdmin: true,
Networks: []string{},
Groups: []string{},
})
peerUpdate := make(chan *models.Node)
go ManageZombies(context.Background(), peerUpdate)
go func() {
for update := range peerUpdate {
//do nothing
logger.Log(3, "received node update", update.Action)
}
}()
}
func TestCheckPorts(t *testing.T) {
h := models.Host{
ID: uuid.New(),
EndpointIP: net.ParseIP("192.168.1.1"),

View file

@ -96,6 +96,7 @@ func CreateHost(h *models.Host) error {
return err
}
h.HostPass = string(hash)
checkForZombieHosts(h)
return UpsertHost(h)
}

View file

@ -534,7 +534,7 @@ func createNode(node *models.Node) error {
if err != nil {
return err
}
CheckZombies(node, host.MacAddress)
CheckZombies(node)
nodebytes, err := json.Marshal(&node)
if err != nil {

View file

@ -301,7 +301,6 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
hostPeerUpdate := models.HostPeerUpdate{
Host: *host,
Server: servercfg.GetServer(),
Network: make(map[string]models.NetworkInfo),
PeerIDs: make(models.HostPeerMap),
ServerVersion: servercfg.GetVersion(),
ServerAddrs: []models.ServerAddr{},
@ -320,10 +319,6 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
if !node.Connected || node.Action == models.NODE_DELETE || node.PendingDelete {
continue
}
hostPeerUpdate.Network[node.Network] = models.NetworkInfo{
DNS: getPeerDNS(node.Network),
}
currentPeers, err := GetNetworkNodes(node.Network)
if err != nil {
log.Println("no network nodes")
@ -395,7 +390,25 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
}
peerConfig.AllowedIPs = allowedips
if node.IsIngressGateway || node.IsEgressGateway {
if peer.IsIngressGateway {
_, extPeerIDAndAddrs, err := getExtPeers(&peer)
if err == nil {
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(extPeerIdAndAddr.Address),
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
},
PeerKey: extPeerIdAndAddr.ID,
Allow: true,
}
}
}
}
if node.IsIngressGateway && peer.IsEgressGateway {
hostPeerUpdate.IngressInfo.EgressRanges = append(hostPeerUpdate.IngressInfo.EgressRanges,
peer.EgressGatewayRanges...)
}
nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(peer.PrimaryAddress()),
@ -508,7 +521,6 @@ func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, err
peerUpdate := models.PeerUpdate{
Network: node.Network,
ServerVersion: ncutils.Version,
DNS: getPeerDNS(node.Network),
PeerIDs: make(models.PeerMap),
}
currentPeers, err := GetNetworkNodes(node.Network)
@ -777,7 +789,6 @@ func GetPeerUpdateLegacy(node *models.Node) (models.PeerUpdate, error) {
})
peerUpdate.Peers = peers
peerUpdate.ServerAddrs = serverNodeAddresses
peerUpdate.DNS = getPeerDNS(node.Network)
peerUpdate.PeerIDs = peerMap
return peerUpdate, nil
}
@ -948,28 +959,6 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
return allowedips
}
func getPeerDNS(network string) string {
var dns string
if nodes, err := GetNetworkNodes(network); err == nil {
for i, node := range nodes {
host, err := GetHost(node.HostID.String())
if err != nil {
logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
continue
}
dns = dns + fmt.Sprintf("%s %s.%s\n", nodes[i].Address, host.Name, nodes[i].Network)
}
}
if customDNSEntries, err := GetCustomDNS(network); err == nil {
for _, entry := range customDNSEntries {
// TODO - filter entries based on ACLs / given peers vs nodes in network
dns = dns + fmt.Sprintf("%s %s.%s\n", entry.Address, entry.Name, entry.Network)
}
}
return dns
}
// GetPeerUpdateForRelayedNode - calculates peer update for a relayed node by getting the relay
// copying the relay node's allowed ips and making appropriate substitutions
func GetPeerUpdateForRelayedNode(node *models.Node, udppeers map[string]string) (models.PeerUpdate, error) {
@ -1108,7 +1097,6 @@ func GetPeerUpdateForRelayedNode(node *models.Node, udppeers map[string]string)
})
peerUpdate.Peers = peers
peerUpdate.ServerAddrs = serverNodeAddresses
peerUpdate.DNS = getPeerDNS(node.Network)
return peerUpdate, nil
}

View file

@ -10,8 +10,12 @@ import (
"github.com/stretchr/testify/assert"
)
func TestNetworkUserLogic(t *testing.T) {
func TestMain(m *testing.M) {
database.InitializeDatabase()
defer database.CloseDB()
}
func TestNetworkUserLogic(t *testing.T) {
networkUser := promodels.NetworkUser{
ID: "helloworld",
}

View file

@ -3,13 +3,11 @@ package pro
import (
"testing"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/models/promodels"
"github.com/stretchr/testify/assert"
)
func TestUserGroupLogic(t *testing.T) {
database.InitializeDatabase()
t.Run("User Groups initialized successfully", func(t *testing.T) {
err := InitializeGroups()

View file

@ -2,7 +2,6 @@ package logic
import (
"context"
"net"
"time"
"github.com/google/uuid"
@ -18,15 +17,16 @@ const (
)
var (
zombies []uuid.UUID
removeZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
newZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
zombies []uuid.UUID
hostZombies []uuid.UUID
newZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
newHostZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
)
// CheckZombies - checks if new node has same macaddress as existing node
// CheckZombies - checks if new node has same hostid as existing node
// if so, existing node is added to zombie node quarantine list
// also cleans up nodes past their expiration date
func CheckZombies(newnode *models.Node, mac net.HardwareAddr) {
func CheckZombies(newnode *models.Node) {
nodes, err := GetNetworkNodes(newnode.Network)
if err != nil {
logger.Log(1, "Failed to retrieve network nodes", newnode.Network, err.Error())
@ -44,6 +44,35 @@ func CheckZombies(newnode *models.Node, mac net.HardwareAddr) {
}
}
// checkForZombieHosts - checks if new host has the same macAddress as an existing host
// if true, existing host is added to host zombie collection
func checkForZombieHosts(h *models.Host) {
hosts, err := GetAllHosts()
if err != nil {
logger.Log(3, "errror retrieving all hosts", err.Error())
}
for _, existing := range hosts {
if existing.ID == h.ID {
//probably an unnecessary check as new host should not be in database yet, but just in case
//skip self
continue
}
if existing.MacAddress.String() == h.MacAddress.String() {
//add to hostZombies
newHostZombie <- existing.ID
//add all nodes belonging to host to zombile list
for _, node := range existing.Nodes {
id, err := uuid.Parse(node)
if err != nil {
logger.Log(3, "error parsing uuid from host.Nodes", err.Error())
continue
}
newHostZombie <- id
}
}
}
}
// ManageZombies - goroutine which adds/removes/deletes nodes from the zombie node quarantine list
func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
logger.Log(2, "Zombie management started")
@ -51,24 +80,12 @@ func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
for {
select {
case <-ctx.Done():
close(peerUpdate)
return
case id := <-newZombie:
logger.Log(1, "adding", id.String(), "to zombie quaratine list")
zombies = append(zombies, id)
case id := <-removeZombie:
found := false
if len(zombies) > 0 {
for i := len(zombies) - 1; i >= 0; i-- {
if zombies[i] == id {
logger.Log(1, "removing zombie from quaratine list", zombies[i].String())
zombies = append(zombies[:i], zombies[i+1:]...)
found = true
}
}
}
if !found {
logger.Log(3, "no zombies found")
}
case id := <-newHostZombie:
hostZombies = append(hostZombies, id)
case <-time.After(time.Second * ZOMBIE_TIMEOUT):
logger.Log(3, "checking for zombie nodes")
if len(zombies) > 0 {
@ -92,6 +109,23 @@ func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
}
}
}
if len(hostZombies) > 0 {
logger.Log(3, "checking host zombies")
for i := len(hostZombies) - 1; i >= 0; i-- {
host, err := GetHost(hostZombies[i].String())
if err != nil {
logger.Log(1, "error retrieving zombie host", err.Error())
logger.Log(1, "deleting ", host.ID.String(), " from zombie list")
zombies = append(zombies[:i], zombies[i+1:]...)
continue
}
if len(host.Nodes) == 0 {
if err := RemoveHost(host); err != nil {
logger.Log(0, "error deleting zombie host", host.ID.String(), err.Error())
}
}
}
}
}
}
}
@ -115,10 +149,10 @@ func InitializeZombies() {
}
if node.HostID == othernode.HostID {
if node.LastCheckIn.After(othernode.LastCheckIn) {
zombies = append(zombies, othernode.ID)
newZombie <- othernode.ID
logger.Log(1, "adding", othernode.ID.String(), "to zombie list")
} else {
zombies = append(zombies, node.ID)
newZombie <- node.ID
logger.Log(1, "adding", node.ID.String(), "to zombie list")
}
}

View file

@ -1,6 +1,45 @@
// TODO: Either add a returnNetwork and returnKey, or delete this
package models
// DNSUpdateAction identifies the action to be performed with the dns update data
type DNSUpdateAction int
const (
// DNSDeleteByIP delete the dns entry
DNSDeleteByIP = iota
// DNSDeleteByName delete the dns entry
DNSDeleteByName
// DNSReplaceName replace the dns entry
DNSReplaceName
// DNSReplaceIP resplace the dns entry
DNSReplaceIP
// DNSInsert insert a new dns entry
DNSInsert
)
func (action DNSUpdateAction) String() string {
return [...]string{"DNSDeleteByIP", "DNSDeletByName", "DNSReplaceName", "DNSReplaceIP", "DNSInsert"}[action]
}
// DNSError.Error implementation of error interface
func (e DNSError) Error() string {
return "error publishing dns update"
}
// DNSError error struct capable of holding multiple error messages
type DNSError struct {
ErrorStrings []string
}
// DNSUpdate data for updating entries in /etc/hosts
type DNSUpdate struct {
Action DNSUpdateAction
Name string
NewName string
Address string
NewAddress string
}
// DNSEntry - a DNS entry represented as struct
type DNSEntry struct {
Address string `json:"address" bson:"address" validate:"ip"`

View file

@ -12,28 +12,27 @@ type PeerUpdate struct {
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
DNS string `json:"dns" bson:"dns" yaml:"dns"`
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
ProxyUpdate ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
}
// HostPeerUpdate - struct for host peer updates
type HostPeerUpdate struct {
Host Host `json:"host" bson:"host" yaml:"host"`
Server string `json:"server" bson:"server" yaml:"server"`
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
Network map[string]NetworkInfo `json:"network" bson:"network" yaml:"network"`
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
PeerIDs HostPeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
ProxyUpdate ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
EgressInfo map[string]EgressInfo `json:"egress_info" bson:"egress_info" yaml:"egress_info"` // map key is node ID
IngressInfo IngressInfo `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
Host Host `json:"host" bson:"host" yaml:"host"`
Server string `json:"server" bson:"server" yaml:"server"`
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
PeerIDs HostPeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
ProxyUpdate ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
EgressInfo map[string]EgressInfo `json:"egress_info" bson:"egress_info" yaml:"egress_info"` // map key is node ID
IngressInfo IngressInfo `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
}
// IngressInfo - struct for ingress info
type IngressInfo struct {
ExtPeers map[string]ExtClientInfo `json:"ext_peers" yaml:"ext_peers"`
ExtPeers map[string]ExtClientInfo `json:"ext_peers" yaml:"ext_peers"`
EgressRanges []string `json:"egress_ranges" yaml:"egress_ranges"`
}
// EgressInfo - struct for egress info
@ -62,11 +61,6 @@ type ExtClientInfo struct {
Peers map[string]PeerRouteInfo `json:"peers" yaml:"peers"`
}
// NetworkInfo - struct for network info
type NetworkInfo struct {
DNS string `json:"dns" bson:"dns" yaml:"dns"`
}
// KeyUpdate - key update struct
type KeyUpdate struct {
Network string `json:"network" bson:"network"`

View file

@ -2,7 +2,7 @@ package models
// moved from controllers need work
//func TestUpdateNetwork(t *testing.T) {
// database.InitializeDatabase()
// initialize()
// createNet()
// network := getNet()
// t.Run("NetID", func(t *testing.T) {

View file

@ -56,7 +56,7 @@ func PublishSingleHostUpdate(host *models.Host) error {
return publish(host, fmt.Sprintf("peers/host/%s/%s", host.ID.String(), servercfg.GetServer()), data)
}
// PublishPeerUpdate --- publishes a peer update to all the peers of a node
// PublishExtPeerUpdate --- publishes a peer update to all the peers of a node
func PublishExtPeerUpdate(node *models.Node) error {
go PublishPeerUpdate()
@ -83,7 +83,7 @@ func NodeUpdate(node *models.Node) error {
logger.Log(2, "error marshalling node update ", err.Error())
return err
}
if err = publish(host, fmt.Sprintf("update/%s/%s", node.Network, node.ID), data); err != nil {
if err = publish(host, fmt.Sprintf("node/update/%s/%s", node.Network, node.ID), data); err != nil {
logger.Log(2, "error publishing node update to peer ", node.ID.String(), err.Error())
return err
}
@ -111,6 +111,279 @@ func HostUpdate(hostUpdate *models.HostUpdate) error {
return nil
}
// ServerStartNotify - notifies all non server nodes to pull changes after a restart
func ServerStartNotify() error {
nodes, err := logic.GetAllNodes()
if err != nil {
return err
}
for i := range nodes {
nodes[i].Action = models.NODE_FORCE_UPDATE
if err = NodeUpdate(&nodes[i]); err != nil {
logger.Log(1, "error when notifying node", nodes[i].ID.String(), "of a server startup")
}
}
return nil
}
// PublishDNSUpdate publishes a dns update to all nodes on a network
func PublishDNSUpdate(network string, dns models.DNSUpdate) error {
nodes, err := logic.GetNetworkNodes(network)
if err != nil {
return err
}
for _, node := range nodes {
host, err := logic.GetHost(node.HostID.String())
if err != nil {
logger.Log(0, "error retrieving host for dns update", host.ID.String(), err.Error())
continue
}
data, err := json.Marshal(dns)
if err != nil {
logger.Log(0, "failed to encode dns data for node", node.ID.String(), err.Error())
}
if err := publish(host, "dns/update/"+host.ID.String()+"/"+servercfg.GetServer(), data); err != nil {
logger.Log(0, "error publishing dns update to host", host.ID.String(), err.Error())
continue
}
logger.Log(3, "published dns update to host", host.ID.String())
}
return nil
}
// PublishAllDNS publishes an array of dns updates (ip / host.network) for each peer to a node joining a network
func PublishAllDNS(newnode *models.Node) error {
alldns := []models.DNSUpdate{}
newnodeHost, err := logic.GetHost(newnode.HostID.String())
if err != nil {
return fmt.Errorf("error retrieving host for dns update %w", err)
}
alldns = append(alldns, getNodeDNS(newnode.Network)...)
alldns = append(alldns, getExtClientDNS(newnode.Network)...)
alldns = append(alldns, getCustomDNS(newnode.Network)...)
data, err := json.Marshal(alldns)
if err != nil {
return fmt.Errorf("error encoding dns data %w", err)
}
if err := publish(newnodeHost, "dns/all/"+newnodeHost.ID.String()+"/"+servercfg.GetServer(), data); err != nil {
return fmt.Errorf("error publishing full dns update to %s, %w", newnodeHost.ID.String(), err)
}
logger.Log(3, "published full dns update to %s", newnodeHost.ID.String())
return nil
}
// PublishDNSDelete publish a dns update deleting a node to all hosts on a network
func PublishDNSDelete(node *models.Node, host *models.Host) error {
dns := models.DNSUpdate{
Action: models.DNSDeleteByIP,
Name: host.Name + "." + node.Network,
}
if node.Address.IP != nil {
dns.Address = node.Address.IP.String()
if err := PublishDNSUpdate(node.Network, dns); err != nil {
return fmt.Errorf("dns update node deletion %w", err)
}
}
if node.Address6.IP != nil {
dns.Address = node.Address6.IP.String()
if err := PublishDNSUpdate(node.Network, dns); err != nil {
return fmt.Errorf("dns update node deletion %w", err)
}
}
return nil
}
// PublishReplaceDNS publish a dns update to replace a dns entry on all hosts in network
func PublishReplaceDNS(oldNode, newNode *models.Node, host *models.Host) error {
dns := models.DNSUpdate{
Action: models.DNSReplaceIP,
Name: host.Name + "." + oldNode.Network,
}
if !oldNode.Address.IP.Equal(newNode.Address.IP) {
dns.Address = oldNode.Address.IP.String()
dns.NewAddress = newNode.Address.IP.String()
if err := PublishDNSUpdate(oldNode.Network, dns); err != nil {
return err
}
}
if !oldNode.Address6.IP.Equal(newNode.Address6.IP) {
dns.Address = oldNode.Address6.IP.String()
dns.NewAddress = newNode.Address6.IP.String()
if err := PublishDNSUpdate(oldNode.Network, dns); err != nil {
return err
}
}
return nil
}
// PublishExtClientDNS publish dns update for new extclient
func PublishExtCLientDNS(client *models.ExtClient) error {
errMsgs := models.DNSError{}
dns := models.DNSUpdate{
Action: models.DNSInsert,
Name: client.ClientID + "." + client.Network,
Address: client.Address,
}
if client.Address != "" {
dns.Address = client.Address
if err := PublishDNSUpdate(client.Network, dns); err != nil {
errMsgs.ErrorStrings = append(errMsgs.ErrorStrings, err.Error())
}
}
if client.Address6 != "" {
dns.Address = client.Address6
if err := PublishDNSUpdate(client.Network, dns); err != nil {
errMsgs.ErrorStrings = append(errMsgs.ErrorStrings, err.Error())
}
}
if len(errMsgs.ErrorStrings) > 0 {
return errMsgs
}
return nil
}
// PublishExtClientDNSUpdate update for extclient name change
func PublishExtClientDNSUpdate(old, new models.ExtClient, network string) error {
dns := models.DNSUpdate{
Action: models.DNSReplaceName,
Name: old.ClientID + "." + network,
NewName: new.ClientID + "." + network,
}
if err := PublishDNSUpdate(network, dns); err != nil {
return err
}
return nil
}
// PublishDeleteExtClientDNS publish dns update to delete extclient entry
func PublishDeleteExtClientDNS(client *models.ExtClient) error {
dns := models.DNSUpdate{
Action: models.DNSDeleteByName,
Name: client.ClientID + "." + client.Network,
}
if err := PublishDNSUpdate(client.Network, dns); err != nil {
return err
}
return nil
}
// PublishCustomDNS publish dns update for new custom dns entry
func PublishCustomDNS(entry *models.DNSEntry) error {
dns := models.DNSUpdate{
Action: models.DNSInsert,
Name: entry.Name + "." + entry.Network,
//entry.Address6 is never used
Address: entry.Address,
}
if err := PublishDNSUpdate(entry.Network, dns); err != nil {
return err
}
return nil
}
// PublishHostDNSUpdate publishes dns update on host name change
func PublishHostDNSUpdate(old, new *models.Host, networks []string) error {
errMsgs := models.DNSError{}
for _, network := range networks {
dns := models.DNSUpdate{
Action: models.DNSReplaceName,
Name: old.Name + "." + network,
NewName: new.Name + "." + network,
}
if err := PublishDNSUpdate(network, dns); err != nil {
errMsgs.ErrorStrings = append(errMsgs.ErrorStrings, err.Error())
}
}
if len(errMsgs.ErrorStrings) > 0 {
return errMsgs
}
return nil
}
func pushMetricsToExporter(metrics models.Metrics) error {
logger.Log(2, "----> Pushing metrics to exporter")
data, err := json.Marshal(metrics)
if err != nil {
return errors.New("failed to marshal metrics: " + err.Error())
}
if token := mqclient.Publish("metrics_exporter", 2, true, data); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
var err error
if token.Error() == nil {
err = errors.New("connection timeout")
} else {
err = token.Error()
}
return err
}
return nil
}
func getNodeDNS(network string) []models.DNSUpdate {
alldns := []models.DNSUpdate{}
dns := models.DNSUpdate{}
nodes, err := logic.GetNetworkNodes(network)
if err != nil {
logger.Log(0, "error retreiving network nodes for network", network, err.Error())
}
for _, node := range nodes {
host, err := logic.GetHost(node.HostID.String())
if err != nil {
logger.Log(0, "error retrieving host for dns update", host.ID.String(), err.Error())
continue
}
dns.Action = models.DNSInsert
dns.Name = host.Name + "." + node.Network
if node.Address.IP != nil {
dns.Address = node.Address.IP.String()
alldns = append(alldns, dns)
}
if node.Address6.IP != nil {
dns.Address = node.Address6.IP.String()
alldns = append(alldns, dns)
}
}
return alldns
}
func getExtClientDNS(network string) []models.DNSUpdate {
alldns := []models.DNSUpdate{}
dns := models.DNSUpdate{}
clients, err := logic.GetNetworkExtClients(network)
if err != nil {
logger.Log(0, "error retrieving extclients", err.Error())
}
for _, client := range clients {
dns.Action = models.DNSInsert
dns.Name = client.ClientID + "." + client.Network
if client.Address != "" {
dns.Address = client.Address
alldns = append(alldns, dns)
}
if client.Address6 != "" {
dns.Address = client.Address
alldns = append(alldns, dns)
}
}
return alldns
}
func getCustomDNS(network string) []models.DNSUpdate {
alldns := []models.DNSUpdate{}
dns := models.DNSUpdate{}
customdns, err := logic.GetCustomDNS(network)
if err != nil {
logger.Log(0, "error retrieving custom dns entries", err.Error())
}
for _, custom := range customdns {
dns.Action = models.DNSInsert
dns.Address = custom.Address
dns.Name = custom.Name + "." + custom.Network
alldns = append(alldns, dns)
}
return alldns
}
// sendPeers - retrieve networks, send peer ports to all peers
func sendPeers() {
@ -144,79 +417,3 @@ func sendPeers() {
}
}
}
// ServerStartNotify - notifies all non server nodes to pull changes after a restart
func ServerStartNotify() error {
nodes, err := logic.GetAllNodes()
if err != nil {
return err
}
for i := range nodes {
nodes[i].Action = models.NODE_FORCE_UPDATE
if err = NodeUpdate(&nodes[i]); err != nil {
logger.Log(1, "error when notifying node", nodes[i].ID.String(), "of a server startup")
}
}
return nil
}
// function to collect and store metrics for server nodes
//func collectServerMetrics(networks []models.Network) {
// if !servercfg.Is_EE {
// return
// }
// if len(networks) > 0 {
// for i := range networks {
// currentNetworkNodes, err := logic.GetNetworkNodes(networks[i].NetID)
// if err != nil {
// continue
// }
// currentServerNodes := logic.GetServerNodes(networks[i].NetID)
// if len(currentServerNodes) > 0 {
// for i := range currentServerNodes {
// if logic.IsLocalServer(&currentServerNodes[i]) {
// serverMetrics := logic.CollectServerMetrics(currentServerNodes[i].ID, currentNetworkNodes)
// if serverMetrics != nil {
// serverMetrics.NodeName = currentServerNodes[i].Name
// serverMetrics.NodeID = currentServerNodes[i].ID
// serverMetrics.IsServer = "yes"
// serverMetrics.Network = currentServerNodes[i].Network
// if err = metrics.GetExchangedBytesForNode(&currentServerNodes[i], serverMetrics); err != nil {
// logger.Log(1, fmt.Sprintf("failed to update exchanged bytes info for server: %s, err: %v",
// currentServerNodes[i].Name, err))
// }
// updateNodeMetrics(&currentServerNodes[i], serverMetrics)
// if err = logic.UpdateMetrics(currentServerNodes[i].ID, serverMetrics); err != nil {
// logger.Log(1, "failed to update metrics for server node", currentServerNodes[i].ID)
// }
// if servercfg.IsMetricsExporter() {
// logger.Log(2, "-------------> SERVER METRICS: ", fmt.Sprintf("%+v", serverMetrics))
// if err := pushMetricsToExporter(*serverMetrics); err != nil {
// logger.Log(2, "failed to push server metrics to exporter: ", err.Error())
// }
// }
// }
// }
// }
// }
// }
// }
//}
func pushMetricsToExporter(metrics models.Metrics) error {
logger.Log(2, "----> Pushing metrics to exporter")
data, err := json.Marshal(metrics)
if err != nil {
return errors.New("failed to marshal metrics: " + err.Error())
}
if token := mqclient.Publish("metrics_exporter", 2, true, data); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
var err error
if token.Error() == nil {
err = errors.New("connection timeout")
} else {
err = token.Error()
}
return err
}
return nil
}

View file

@ -166,13 +166,16 @@ func GetPublicIP(api string) (string, error) {
if err != nil {
continue
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
var bodyBytes []byte
bodyBytes, err = io.ReadAll(resp.Body)
if err != nil {
if resp.Body != nil {
_ = resp.Body.Close()
}
continue
}
_ = resp.Body.Close()
endpoint = string(bodyBytes)
break
}

View file

@ -29,6 +29,7 @@ fi
unset INSTALL_TYPE
unset BUILD_TYPE
unset BUILD_TAG
unset IMAGE_TAG
usage () {(
echo "usage: ./nm-quick.sh [-e] [-b buildtype] [-t tag]"

View file

@ -3,7 +3,6 @@ package stunserver
import (
"context"
"fmt"
"log"
"net"
"os"
"os/signal"
@ -71,7 +70,6 @@ func (s *Server) serveConn(c net.PacketConn, res, req *stun.Message) error {
logger.Log(1, "ReadFrom: %v", err.Error())
return nil
}
log.Printf("read %d bytes from %s\n", n, addr)
if _, err = req.Write(buf[:n]); err != nil {
logger.Log(1, "Write: %v", err.Error())
return err