fixed network tests that failed with nodes

This commit is contained in:
Matthew R Kasun
2021-04-24 18:03:26 -04:00
parent f28937c1f6
commit ae826002cd
6 changed files with 1165 additions and 721 deletions

View File

@@ -1,19 +1,19 @@
package controller
import (
"gopkg.in/go-playground/validator.v9"
"log"
"fmt"
"golang.org/x/crypto/bcrypt"
"github.com/gravitl/netmaker/mongoconn"
"github.com/gravitl/netmaker/functions"
"context"
"go.mongodb.org/mongo-driver/bson"
"time"
"fmt"
"log"
"net"
"github.com/gravitl/netmaker/models"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
"github.com/gravitl/netmaker/functions"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"golang.org/x/crypto/bcrypt"
"gopkg.in/go-playground/validator.v9"
)
func GetPeersList(networkName string) ([]models.PeersResponse, error) {
@@ -58,7 +58,6 @@ func GetPeersList(networkName string) ([]models.PeersResponse, error) {
return peers, err
}
func ValidateNode(operation string, networkName string, node models.Node) error {
v := validator.New()
@@ -67,16 +66,15 @@ func ValidateNode(operation string, networkName string, node models.Node) error
//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
isIpv4 := functions.IsIpv4Net(node.Endpoint)
notEmptyCheck := node.Endpoint != ""
return (notEmptyCheck && isIpv4) || operation == "update"
return (notEmptyCheck && isIpv4)
})
_ = v.RegisterValidation("localaddress_check", func(fl validator.FieldLevel) bool {
//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
isIpv4 := functions.IsIpv4Net(node.LocalAddress)
notEmptyCheck := node.LocalAddress != ""
return (notEmptyCheck && isIpv4) || operation == "update"
return (notEmptyCheck && isIpv4)
})
_ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
var isFieldUnique bool = functions.IsFieldUnique(networkName, "macaddress", node.MacAddress)
return isFieldUnique || operation == "update"
@@ -99,12 +97,12 @@ func ValidateNode(operation string, networkName string, node models.Node) error
_ = v.RegisterValidation("pubkey_check", func(fl validator.FieldLevel) bool {
notEmptyCheck := node.PublicKey != ""
isBase64 := functions.IsBase64(node.PublicKey)
return (notEmptyCheck && isBase64) || operation == "update"
return (notEmptyCheck && isBase64)
})
_ = v.RegisterValidation("password_check", func(fl validator.FieldLevel) bool {
notEmptyCheck := node.Password != ""
goodLength := len(node.Password) > 5
return (notEmptyCheck && goodLength) || operation == "update"
return (notEmptyCheck && goodLength)
})
err := v.Struct(node)
@@ -117,7 +115,6 @@ func ValidateNode(operation string, networkName string, node models.Node) error
return err
}
func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
//Question: Is there a better way of doing this than a bunch of "if" statements? probably...
//Eventually, lets have a better way to check if any of the fields are filled out...
@@ -221,6 +218,9 @@ func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
return nodeupdate, errN
}
if nodechange.MacAddress != "" {
queryMac = nodechange.MacAddress
}
returnnode, errN := GetNode(queryMac, queryNetwork)
defer cancel()
@@ -285,7 +285,6 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
//set password to encrypted password
node.Password = string(hash)
node.Network = networkName
//node.SetDefaults()
@@ -324,7 +323,6 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// insert our node to the node db.
result, err := collection.InsertOne(ctx, node)
_ = result
@@ -466,5 +464,3 @@ func TimestampNode(node models.Node, updatecheckin bool, updatepeers bool, updat
return err
}

View File

@@ -387,6 +387,12 @@ func checkIn(w http.ResponseWriter, r *http.Request) {
}
//TODO: check node last modified vs network last modified
//Get Updated node to return
node, err = GetNode(params["macaddress"], params["network"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(node)
@@ -660,6 +666,10 @@ func validateGateway(gateway models.GatewayRequest) error {
if empty || !isIpv4 {
err = errors.New("IP Range Not Valid")
}
empty = gateway.Interface == ""
if empty {
err = errors.New("Interface cannot be empty")
}
return err
}

View File

@@ -5,20 +5,21 @@
package functions
import (
"fmt"
"errors"
"math/rand"
"time"
"context"
"encoding/base64"
"strings"
"errors"
"fmt"
"math/rand"
"net"
"strings"
"time"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
//Takes in an arbitrary field and value for field and checks to see if any other
@@ -48,7 +49,6 @@ func CreateServerToken(netID string) (string, error) {
privAddr = network.LocalRange
}
fmt.Println("Token details:")
fmt.Println(" grpc address + port: " + address)
fmt.Println(" network: " + netID)
@@ -60,7 +60,6 @@ func CreateServerToken(netID string) (string, error) {
fmt.Println(" access string: " + accesskey.AccessString)
network.AccessKeys = append(network.AccessKeys, accesskey)
collection := mongoconn.Client.Database("netmaker").Collection("networks")
@@ -108,7 +107,7 @@ func IsFieldUnique(network string, field string, value string) bool {
return isunique
}
if (node.Name != "") {
if node.Name != "" {
isunique = false
}
@@ -185,6 +184,7 @@ func UpdateNetworkNodeAddresses(networkName string) error {
return err
}
//TODO TODO TODO!!!!!
func UpdateNetworkPrivateAddresses(networkName string) error {
@@ -261,7 +261,6 @@ func IsNetworkDisplayNameUnique(name string) (bool, error){
return false, err
}
for i := 0; i < len(dbs); i++ {
if name == dbs[i].DisplayName {
@@ -274,7 +273,7 @@ func IsNetworkDisplayNameUnique(name string) (bool, error){
func GetNetworkNodeNumber(networkName string) (int, error) {
collection := mongoconn.Client.Database("wirecat").Collection("nodes")
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -292,7 +291,6 @@ func GetNetworkNodeNumber(networkName string) (int, error){
return returncount, err
}
//Kind of a weird name. Should just be GetNetworks I think. Consider changing.
//Anyway, returns all the networks
func ListNetworks() ([]models.Network, error) {
@@ -355,6 +353,7 @@ func IsKeyValid(networkname string, keyvalue string) bool{
}
return isvalid
}
//TODO: Contains a fatal error return. Need to change
//This just gets a network object from a network name
//Should probably just be GetNetwork. kind of a dumb name.
@@ -459,7 +458,6 @@ func NameInNodeCharSet(name string) bool{
return true
}
//This returns a node based on its mac address.
//The mac address acts as the Unique ID for nodes.
//Is this a dumb thing to do? I thought it was cool but maybe it's dumb.
@@ -547,8 +545,6 @@ func GetGlobalConfig() (bool, models.GlobalConfig, error) {
return create, globalconf, err
}
//generate an access key value
func GenKey() string {
@@ -606,7 +602,7 @@ func IsIPUnique(network string, ip string) bool {
return isunique
}
if (node.Address == ip) {
if node.Address == ip {
isunique = false
}
return isunique
@@ -656,6 +652,7 @@ func DecrimentKey(networkName string, keyvalue string) {
return
}
}
//takes the logic from controllers.deleteKey
func DeleteKey(network models.Network, i int) {
@@ -684,6 +681,7 @@ func DeleteKey(network models.Network, i int) {
return
}
}
//increments an IP over the previous
func Inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {

View File

@@ -216,22 +216,14 @@ func networkExists(t *testing.T) bool {
return false
}
func TestJunk(t *testing.T) {
deleteNetworks(t)
}
func deleteNetworks(t *testing.T) {
//delete all network nodes
var nodes []models.ReturnNode
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
if response.StatusCode == http.StatusOK {
err = json.NewDecoder(response.Body).Decode(&nodes)
response.Body.Close()
assert.Nil(t, err, err)
for _, node := range nodes {
resp, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/skynet/"+node.MacAddress, "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
}
response, err = api(t, "", http.MethodGet, baseURL+"/api/networks", "secretkey")
//delete all node
deleteAllNodes(t)
response, err := api(t, "", http.MethodGet, baseURL+"/api/networks", "secretkey")
assert.Nil(t, err, err)
if response.StatusCode == http.StatusOK {
defer response.Body.Close()
@@ -260,12 +252,24 @@ func getNetworkNodes(t *testing.T) []models.ReturnNode {
return nodes
}
func deleteNode(t *testing.T, node models.ReturnNode) {
response, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/skynet/"+node.MacAddress, "secretkey")
func deleteNode(t *testing.T) {
response, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
}
func deleteAllNodes(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
var nodes []models.ReturnNode
defer response.Body.Close()
json.NewDecoder(response.Body).Decode(&nodes)
for _, node := range nodes {
resp, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/"+node.Network+"/"+node.MacAddress, "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
}
func createNode(t *testing.T) {
var node models.Node
key := createAccessKey(t)
@@ -291,3 +295,9 @@ func getNode(t *testing.T) models.Node {
assert.Nil(t, err, err)
return node
}
func setup(t *testing.T) {
deleteNetworks(t)
createNetwork(t)
createNode(t)
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/mongo"
)
func TestCreateNetwork(t *testing.T) {
@@ -118,6 +117,7 @@ func TestGetNetwork(t *testing.T) {
func TestDeleteNetwork(t *testing.T) {
t.Run("InvalidKey", func(t *testing.T) {
setup(t)
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/skynet", "badkey")
assert.Nil(t, err, err)
defer response.Body.Close()
@@ -128,17 +128,6 @@ func TestDeleteNetwork(t *testing.T) {
assert.Equal(t, http.StatusUnauthorized, message.Code)
assert.Equal(t, "W1R3: You are unauthorized to access this endpoint.", message.Message)
})
t.Run("ValidKey", func(t *testing.T) {
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/skynet", "secretkey")
assert.Nil(t, err, err)
defer response.Body.Close()
var message mongo.DeleteResult
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, int64(1), message.DeletedCount)
})
t.Run("Badnetwork", func(t *testing.T) {
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/badnetwork", "secretkey")
assert.Nil(t, err, err)
@@ -150,7 +139,33 @@ func TestDeleteNetwork(t *testing.T) {
assert.Equal(t, http.StatusNotFound, response.StatusCode)
})
t.Run("NodesExist", func(t *testing.T) {
setup(t)
node := getNode(t)
t.Log(node)
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusForbidden, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Contains(t, message.Message, "Node check failed")
assert.Equal(t, http.StatusForbidden, message.Code)
})
t.Run("ValidKey", func(t *testing.T) {
type Message struct {
DeletedCount int64
}
setup(t)
deleteAllNodes(t)
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/skynet", "secretkey")
assert.Nil(t, err, err)
defer response.Body.Close()
var message Message
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, int64(1), message.DeletedCount)
})
}

View File

@@ -4,23 +4,34 @@ import (
"encoding/json"
"net/http"
"testing"
"time"
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
"golang.org/x/crypto/bcrypt"
)
func setup(t *testing.T) {
deleteNetworks(t)
createNetwork(t)
createNode(t)
}
func TestJunk(t *testing.T) {
deleteNetworks(t)
func TestRainyDay(t *testing.T) {
t.Run("badkey", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes", "badkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
})
t.Run("badURL", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/adm/skynet/01:02:03:04:05:07", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusNotFound, response.StatusCode)
})
t.Run("NonExistentNetwork", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/badnet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusNotFound, response.StatusCode)
})
}
func TestGetAllNodes(t *testing.T) {
setup(t)
t.Run("NodesExist", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
@@ -28,13 +39,24 @@ func TestGetAllNodes(t *testing.T) {
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&nodes)
assert.Nil(t, err, err)
for _, node := range nodes {
assert.NotNil(t, node, "empty node")
}
assert.NotEmpty(t, nodes)
})
t.Run("NodeDoesNotExist", func(t *testing.T) {
deleteNode(t)
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
var nodes []models.ReturnNode
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&nodes)
assert.Nil(t, err, err)
assert.Empty(t, nodes)
})
}
func TestGetNetworkNodes(t *testing.T) {
setup(t)
t.Run("NodeExists", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
@@ -42,13 +64,24 @@ func TestGetNetworkNodes(t *testing.T) {
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&nodes)
assert.Nil(t, err, err)
for _, node := range nodes {
assert.NotNil(t, node, "empty node")
}
assert.NotEmpty(t, nodes)
})
t.Run("NodeDoesNotExit", func(t *testing.T) {
deleteNode(t)
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
var nodes []models.ReturnNode
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&nodes)
assert.Nil(t, err, err)
assert.Empty(t, nodes)
})
}
func TestGetNode(t *testing.T) {
setup(t)
t.Run("NodeExists", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
@@ -57,22 +90,128 @@ func TestGetNode(t *testing.T) {
err = json.NewDecoder(response.Body).Decode(&node)
assert.Nil(t, err, err)
assert.Equal(t, "01:02:03:04:05:06", node.MacAddress)
})
t.Run("NodeDoesNotExist", func(t *testing.T) {
deleteNode(t)
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, response.StatusCode)
})
}
func TestUpdateNode(t *testing.T) {
var data models.Node
setup(t)
var data struct {
Name string
}
t.Run("UpdateMulti", func(t *testing.T) {
data.MacAddress = "01:02:03:04:05:05"
data.Name = "NewName"
data.PublicKey = "DM5qhLAE20PG9BbfBCgfr+Ac9D2NDOwCtY1rbYDLf34="
data.Password = "newpass"
data.LocalAddress = "192.168.0.2"
data.Endpoint = "10.100.100.5"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
var node models.Node
defer response.Body.Close()
var node models.Node
t.Log(response.Body)
err = json.NewDecoder(response.Body).Decode(&node)
assert.Nil(t, err, err)
assert.Equal(t, data.Name, node.Name)
assert.Equal(t, data.PublicKey, node.PublicKey)
err = bcrypt.CompareHashAndPassword([]byte(node.Password), []byte(data.Password))
assert.Nil(t, err, err)
assert.Equal(t, data.LocalAddress, node.LocalAddress)
assert.Equal(t, data.Endpoint, node.Endpoint)
})
t.Run("InvalidMacAddress", func(t *testing.T) {
data.MacAddress = "10:11:12:13:14:15:16"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'MacAddress' failed")
})
t.Run("InvalidEndpoint", func(t *testing.T) {
data.Endpoint = "10.10.10.300"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'Endpoint' failed")
})
t.Run("InvalidLocalAddress", func(t *testing.T) {
data.LocalAddress = "10.10.10.300"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'LocalAddress' failed")
})
t.Run("InvalidName", func(t *testing.T) {
var data struct {
Name string
}
data.Name = "New*Name"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'Name' failed")
})
t.Run("InvalidPublicKey", func(t *testing.T) {
data.PublicKey = "xxx"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'PublicKey' failed")
})
t.Run("InvalidPassword", func(t *testing.T) {
data.Password = "1234"
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'Password' failed")
})
t.Run("EmptyPassword", func(t *testing.T) {
data.Password = ""
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'Password' failed")
})
}
func TestDeleteNode(t *testing.T) {
@@ -103,9 +242,10 @@ func TestDeleteNode(t *testing.T) {
}
func TestCheckIn(t *testing.T) {
//get node
//oldNode := getNode(t)
setup(t)
oldNode := getNode(t)
time.Sleep(1 * time.Second)
t.Run("Valid", func(t *testing.T) {
response, err := api(t, "", http.MethodPost, baseURL+"/api/nodes/skynet/01:02:03:04:05:06/checkin", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
@@ -113,13 +253,27 @@ func TestCheckIn(t *testing.T) {
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&node)
assert.Nil(t, err, err)
//assert.Greater(t, node.LastCheckIn, oldNode.LastCheckin)
assert.Greater(t, node.LastCheckIn, oldNode.LastCheckIn)
})
t.Run("NodeDoesNotExist", func(t *testing.T) {
deleteNode(t)
response, err := api(t, "", http.MethodPost, baseURL+"/api/nodes/skynet/01:02:03:04:05:06/checkin", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, response.StatusCode)
var message models.ErrorResponse
defer response.Body.Close()
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, message.Code)
assert.Equal(t, "mongo: no documents in result", message.Message)
})
}
func TestCreateGateway(t *testing.T) {
setup(t)
//assert.False(t, node.IsGateway)
var gateway models.GatewayRequest
t.Run("Valid", func(t *testing.T) {
gateway.RangeString = "0.0.0.0/0"
gateway.Interface = "eth0"
response, err := api(t, gateway, http.MethodPost, baseURL+"/api/nodes/skynet/01:02:03:04:05:06/creategateway", "secretkey")
@@ -130,6 +284,33 @@ func TestCreateGateway(t *testing.T) {
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.True(t, message.IsGateway)
})
t.Run("BadRange", func(t *testing.T) {
gateway.RangeString = "0.0.0.0/36"
gateway.Interface = "eth0"
response, err := api(t, gateway, http.MethodPost, baseURL+"/api/nodes/skynet/01:02:03:04:05:06/creategateway", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, message.Code)
assert.Equal(t, "IP Range Not Valid", message.Message)
})
t.Run("BadInterface", func(t *testing.T) {
gateway.RangeString = "0.0.0.0/0"
gateway.Interface = ""
response, err := api(t, gateway, http.MethodPost, baseURL+"/api/nodes/skynet/01:02:03:04:05:06/creategateway", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusInternalServerError, message.Code)
assert.Equal(t, "Interface cannot be empty", message.Message)
})
}
func TestDeleteGateway(t *testing.T) {
@@ -158,8 +339,173 @@ func TestUncordonNode(t *testing.T) {
}
func TestCreateNode(t *testing.T) {
setup(t)
key := createAccessKey(t)
t.Run("NodeExists", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
assert.Contains(t, message.Message, "Field validation for 'MacAddress' failed on the 'macaddress_unique' tag")
})
t.Run("BadKey", func(t *testing.T) {
deleteNode(t)
var node models.Node
node.AccessKey = "badkey"
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
assert.Contains(t, message.Message, "W1R3: Key invalid, or none provided")
})
t.Run("BadMac", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "badmac"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'MacAddress' failed on the 'macaddress_valid' tag")
})
t.Run("BadPublicKey", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "xxx"
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'PublicKey' failed")
})
t.Run("BadPass", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = ""
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Error:Field validation for 'Password' failed")
})
t.Run("BadLocalAddress", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.300.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'LocalAddress' failed")
})
t.Run("BadEndpoint", func(t *testing.T) {
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.300.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Contains(t, message.Message, "Field validation for 'Endpoint' failed")
})
t.Run("NetworkDoesNotExist", func(t *testing.T) {
deleteNetworks(t)
createNetwork(t)
var node models.Node
node.AccessKey = key.Value
node.MacAddress = "01:02:03:04:05:06"
node.Name = "myNode"
node.PublicKey = "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
node.Password = "tobedetermined"
node.LocalAddress = "192.168.0.1"
node.Endpoint = "10.100.100.4"
response, err := api(t, node, http.MethodPost, "http://localhost:8081:/api/nodes/skynet", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusNotFound, response.StatusCode)
defer response.Body.Close()
var message models.ErrorResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusNotFound, message.Code)
assert.Contains(t, "W1R3: Network does not exist! ", message.Message)
})
t.Run("Valid", func(t *testing.T) {
setup(t)
deleteNode(t)
key := createAccessKey(t)
var node models.Node
@@ -179,18 +525,30 @@ func TestCreateNode(t *testing.T) {
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, node.Name, message.Name)
t.Log(message.Password)
t.Log(message)
})
}
func TestGetLastModified(t *testing.T) {
deleteNetworks(t)
createNetwork(t)
t.Run("Valid", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/adm/skynet/lastmodified", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.NotNil(t, response.Body, "no time returned")
})
deleteNetworks(t)
t.Run("NoNetwork", func(t *testing.T) {
response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/adm/skynet/lastmodified", "secretkey")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusNotFound, response.StatusCode)
})
}
func TestNodeAuthenticate(t *testing.T) {
setup(t)
t.Run("Valid", func(t *testing.T) {
var authRequest models.AuthParams
authRequest.MacAddress = "01:02:03:04:05:06"
authRequest.Password = "tobedetermined"
@@ -203,4 +561,61 @@ func TestNodeAuthenticate(t *testing.T) {
assert.Nil(t, err, err)
assert.Equal(t, http.StatusOK, message.Code)
assert.Equal(t, "W1R3: Device 01:02:03:04:05:06 Authorized", message.Message)
})
t.Run("MacEmpty", func(t *testing.T) {
var authRequest models.AuthParams
authRequest.MacAddress = ""
authRequest.Password = "tobedetermined"
response, err := api(t, authRequest, http.MethodPost, "http://localhost:8081:/api/nodes/adm/skynet/authenticate", "")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.SuccessResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Equal(t, "W1R3: MacAddress can't be empty", message.Message)
})
t.Run("EmptyPass", func(t *testing.T) {
var authRequest models.AuthParams
authRequest.MacAddress = "01:02:03:04:05:06"
authRequest.Password = ""
response, err := api(t, authRequest, http.MethodPost, "http://localhost:8081:/api/nodes/adm/skynet/authenticate", "")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.SuccessResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Equal(t, "W1R3: Password can't be empty", message.Message)
})
t.Run("BadPass", func(t *testing.T) {
var authRequest models.AuthParams
authRequest.MacAddress = "01:02:03:04:05:06"
authRequest.Password = "badpass"
response, err := api(t, authRequest, http.MethodPost, "http://localhost:8081:/api/nodes/adm/skynet/authenticate", "")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.SuccessResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Equal(t, "crypto/bcrypt: hashedPassword is not the hash of the given password", message.Message)
})
t.Run("BadMac", func(t *testing.T) {
var authRequest models.AuthParams
authRequest.MacAddress = "01:02:03:04:05:07"
authRequest.Password = "tobedetermined"
response, err := api(t, authRequest, http.MethodPost, "http://localhost:8081:/api/nodes/adm/skynet/authenticate", "")
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
defer response.Body.Close()
var message models.SuccessResponse
err = json.NewDecoder(response.Body).Decode(&message)
assert.Nil(t, err, err)
assert.Equal(t, http.StatusBadRequest, message.Code)
assert.Equal(t, "mongo: no documents in result", message.Message)
})
}