netmaker/functions/helpers.go

779 lines
18 KiB
Go
Raw Normal View History

2021-03-26 00:17:52 +08:00
//TODO: Consider restructuring this file/folder "github.com/gorilla/handlers"
//It may make more sense to split into different files and not call it "helpers"
package functions
import (
"context"
"encoding/base64"
"errors"
"fmt"
"math/rand"
"net"
"strings"
"time"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn"
2021-05-06 08:41:28 +08:00
"github.com/gravitl/netmaker/servercfg"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
2021-03-26 00:17:52 +08:00
)
//Takes in an arbitrary field and value for field and checks to see if any other
//node has that value for the same field within the network
func CreateServerToken(netID string) (string, error) {
2021-04-15 21:48:14 +08:00
fmt.Println("Creating token.")
var network models.Network
var accesskey models.AccessKey
network, err := GetParentNetwork(netID)
if err != nil {
return "", err
}
accesskey.Name = GenKeyName()
accesskey.Value = GenKey()
accesskey.Uses = 1
2021-05-06 08:41:28 +08:00
address := "127.0.0.1:" + servercfg.GetGRPCPort()
2021-04-15 21:48:14 +08:00
privAddr := ""
if *network.IsLocal {
privAddr = network.LocalRange
}
2021-04-15 21:48:14 +08:00
accessstringdec := address + "|" + netID + "|" + accesskey.Value + "|" + privAddr
accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
fmt.Println(" access string: " + accesskey.AccessString)
network.AccessKeys = append(network.AccessKeys, accesskey)
collection := mongoconn.Client.Database("netmaker").Collection("networks")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// Create filter
filter := bson.M{"netid": netID}
// Read update model from body request
fmt.Println("Adding key to " + network.NetID)
// prepare update model.
update := bson.D{
{"$set", bson.D{
{"accesskeys", network.AccessKeys},
}},
}
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
defer cancel()
if errN != nil {
return "", errN
}
return accesskey.AccessString, nil
}
func IsFieldUnique(network string, field string, value string) bool {
2021-03-26 00:17:52 +08:00
var node models.Node
isunique := true
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{field: value, "network": network}
2021-03-26 00:17:52 +08:00
err := collection.FindOne(ctx, filter).Decode(&node)
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
if err != nil {
2021-03-26 00:17:52 +08:00
return isunique
}
2021-03-26 00:17:52 +08:00
if node.Name != "" {
isunique = false
}
2021-03-26 00:17:52 +08:00
return isunique
2021-03-26 00:17:52 +08:00
}
func NetworkExists(name string) (bool, error) {
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("networks")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"netid": name}
2021-03-26 00:17:52 +08:00
var result bson.M
err := collection.FindOne(ctx, filter).Decode(&result)
2021-03-26 00:17:52 +08:00
defer cancel()
if err != nil {
if err == mongo.ErrNoDocuments {
2021-04-06 20:24:57 +08:00
return false, nil
2021-03-26 00:17:52 +08:00
}
}
return true, err
}
//TODO: This is very inefficient (N-squared). Need to find a better way.
//Takes a list of nodes in a network and iterates through
2021-03-26 00:17:52 +08:00
//for each node, it gets a unique address. That requires checking against all other nodes once more
func UpdateNetworkNodeAddresses(networkName string) error {
2021-03-26 00:17:52 +08:00
//Connection mongoDB with mongoconn class
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"network": networkName}
cur, err := collection.Find(ctx, filter)
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
for cur.Next(context.TODO()) {
2021-03-26 00:17:52 +08:00
var node models.Node
2021-03-26 00:17:52 +08:00
err := cur.Decode(&node)
2021-03-26 00:17:52 +08:00
if err != nil {
fmt.Println("error in node address assignment!")
return err
}
ipaddr, iperr := UniqueAddress(networkName)
if iperr != nil {
2021-03-26 00:17:52 +08:00
fmt.Println("error in node address assignment!")
return iperr
}
2021-03-26 00:17:52 +08:00
filter := bson.M{"macaddress": node.MacAddress}
update := bson.D{{"$set", bson.D{{"address", ipaddr}}}}
2021-03-26 00:17:52 +08:00
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&node)
defer cancel()
if errN != nil {
2021-03-26 00:17:52 +08:00
return errN
}
}
2021-03-26 00:17:52 +08:00
return err
2021-03-26 00:17:52 +08:00
}
2021-04-13 11:19:01 +08:00
//TODO TODO TODO!!!!!
func UpdateNetworkPrivateAddresses(networkName string) error {
2021-04-13 11:19:01 +08:00
//Connection mongoDB with mongoconn class
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
2021-04-13 11:19:01 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-04-13 11:19:01 +08:00
filter := bson.M{"network": networkName}
cur, err := collection.Find(ctx, filter)
2021-04-13 11:19:01 +08:00
if err != nil {
return err
}
2021-04-13 11:19:01 +08:00
defer cancel()
2021-04-13 11:19:01 +08:00
for cur.Next(context.TODO()) {
2021-04-13 11:19:01 +08:00
var node models.Node
2021-04-13 11:19:01 +08:00
err := cur.Decode(&node)
if err != nil {
fmt.Println("error in node address assignment!")
return err
}
ipaddr, iperr := UniqueAddress(networkName)
if iperr != nil {
fmt.Println("error in node address assignment!")
return iperr
}
2021-04-13 11:19:01 +08:00
filter := bson.M{"macaddress": node.MacAddress}
update := bson.D{{"$set", bson.D{{"address", ipaddr}}}}
2021-04-13 11:19:01 +08:00
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&node)
2021-04-13 11:19:01 +08:00
defer cancel()
if errN != nil {
return errN
}
}
2021-04-13 11:19:01 +08:00
return err
2021-04-13 11:19:01 +08:00
}
2021-03-26 00:17:52 +08:00
//Checks to see if any other networks have the same name (id)
func IsNetworkNameUnique(name string) (bool, error) {
2021-03-26 00:17:52 +08:00
isunique := true
2021-03-26 00:17:52 +08:00
dbs, err := ListNetworks()
2021-04-13 11:19:01 +08:00
if err != nil {
return false, err
}
2021-03-26 00:17:52 +08:00
for i := 0; i < len(dbs); i++ {
if name == dbs[i].NetID {
2021-03-26 00:17:52 +08:00
isunique = false
}
}
return isunique, nil
2021-03-26 00:17:52 +08:00
}
func IsNetworkDisplayNameUnique(name string) (bool, error) {
2021-03-26 00:17:52 +08:00
isunique := true
2021-04-13 11:19:01 +08:00
dbs, err := ListNetworks()
if err != nil {
return false, err
}
2021-03-26 00:17:52 +08:00
for i := 0; i < len(dbs); i++ {
2021-03-26 00:17:52 +08:00
if name == dbs[i].DisplayName {
isunique = false
}
}
2021-03-26 00:17:52 +08:00
return isunique, nil
2021-04-13 11:19:01 +08:00
}
func GetNetworkNodeNumber(networkName string) (int, error) {
2021-04-13 11:19:01 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
2021-04-13 11:19:01 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-04-13 11:19:01 +08:00
filter := bson.M{"network": networkName}
count, err := collection.CountDocuments(ctx, filter)
2021-04-13 11:19:01 +08:00
returncount := int(count)
//not sure if this is the right way of handling this error...
if err != nil {
return 9999, err
}
2021-04-13 11:19:01 +08:00
defer cancel()
2021-04-13 11:19:01 +08:00
return returncount, err
2021-03-26 00:17:52 +08:00
}
//Kind of a weird name. Should just be GetNetworks I think. Consider changing.
//Anyway, returns all the networks
func ListNetworks() ([]models.Network, error) {
2021-04-13 11:19:01 +08:00
var networks []models.Network
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("networks")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
cur, err := collection.Find(ctx, bson.M{}, options.Find().SetProjection(bson.M{"_id": 0}))
2021-03-26 00:17:52 +08:00
if err != nil {
return networks, err
}
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
for cur.Next(context.TODO()) {
2021-03-26 00:17:52 +08:00
var network models.Network
err := cur.Decode(&network)
if err != nil {
return networks, err
}
2021-03-26 00:17:52 +08:00
// add network our array
networks = append(networks, network)
}
2021-03-26 00:17:52 +08:00
if err := cur.Err(); err != nil {
return networks, err
}
2021-03-26 00:17:52 +08:00
return networks, err
2021-03-26 00:17:52 +08:00
}
//Checks to see if access key is valid
//Does so by checking against all keys and seeing if any have the same value
//may want to hash values before comparing...consider this
//TODO: No error handling!!!!
func IsKeyValid(networkname string, keyvalue string) bool {
2021-03-26 00:17:52 +08:00
network, _ := GetParentNetwork(networkname)
2021-03-26 00:17:52 +08:00
var key models.AccessKey
foundkey := false
isvalid := false
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
currentkey := network.AccessKeys[i]
if currentkey.Value == keyvalue {
2021-03-26 00:17:52 +08:00
key = currentkey
foundkey = true
}
}
if foundkey {
if key.Uses > 0 {
isvalid = true
2021-03-26 00:17:52 +08:00
}
}
return isvalid
}
2021-03-26 00:17:52 +08:00
//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.
//Used in contexts where it's not the Parent network.
func GetParentNetwork(networkname string) (models.Network, error) {
2021-03-26 00:17:52 +08:00
var network models.Network
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("networks")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"netid": networkname}
err := collection.FindOne(ctx, filter).Decode(&network)
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
if err != nil {
return network, err
}
2021-03-26 00:17:52 +08:00
return network, nil
2021-03-26 00:17:52 +08:00
}
2021-04-28 11:17:59 +08:00
func IsIpNet(host string) bool {
return net.ParseIP(host) != nil
2021-03-26 00:17:52 +08:00
}
//Similar to above but checks if Cidr range is valid
//At least this guy's got some print statements
//still not good error handling
2021-04-28 11:17:59 +08:00
func IsIpCIDR(host string) bool {
2021-03-26 00:17:52 +08:00
ip, ipnet, err := net.ParseCIDR(host)
2021-03-26 00:17:52 +08:00
if err != nil {
fmt.Println(err)
fmt.Println("Address Range is not valid!")
return false
}
2021-03-26 00:17:52 +08:00
return ip != nil && ipnet != nil
2021-03-26 00:17:52 +08:00
}
//This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
func IsBase64(s string) bool {
_, err := base64.StdEncoding.DecodeString(s)
return err == nil
}
//This should probably just be called GetNode
//It returns a node based on the ID of the node.
//Why do we need this?
//TODO: Check references. This seems unnecessary.
func GetNodeObj(id primitive.ObjectID) models.Node {
var node models.Node
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"_id": id}
err := collection.FindOne(ctx, filter).Decode(&node)
2021-03-26 00:17:52 +08:00
defer cancel()
if err != nil {
fmt.Println(err)
2021-03-26 00:17:52 +08:00
fmt.Println("Did not get the node...")
return node
}
2021-03-26 00:17:52 +08:00
fmt.Println("Got node " + node.Name)
return node
2021-03-26 00:17:52 +08:00
}
//This checks to make sure a network name is valid.
2021-03-26 00:17:52 +08:00
//Switch to REGEX?
func NameInNetworkCharSet(name string) bool {
2021-03-26 00:17:52 +08:00
charset := "abcdefghijklmnopqrstuvwxyz1234567890-_"
for _, char := range name {
if !strings.Contains(charset, strings.ToLower(string(char))) {
return false
}
}
return true
}
2021-04-27 11:39:15 +08:00
func NameInDNSCharSet(name string) bool {
2021-05-01 19:57:49 +08:00
charset := "abcdefghijklmnopqrstuvwxyz1234567890-."
2021-04-27 11:39:15 +08:00
2021-05-01 19:57:49 +08:00
for _, char := range name {
if !strings.Contains(charset, strings.ToLower(string(char))) {
return false
}
}
return true
}
2021-04-27 11:39:15 +08:00
func NameInNodeCharSet(name string) bool {
2021-03-26 00:17:52 +08:00
charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
2021-03-26 00:17:52 +08:00
for _, char := range name {
if !strings.Contains(charset, strings.ToLower(string(char))) {
return false
}
}
return true
2021-03-26 00:17:52 +08:00
}
//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.
//It doesn't really provide a tangible benefit over a random ID
func GetNodeByMacAddress(network string, macaddress string) (models.Node, error) {
2021-03-26 00:17:52 +08:00
var node models.Node
2021-03-26 00:17:52 +08:00
filter := bson.M{"macaddress": macaddress, "network": network}
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err := collection.FindOne(ctx, filter).Decode(&node)
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
if err != nil {
return node, err
}
return node, nil
2021-03-26 00:17:52 +08:00
}
//This returns a unique address for a node to use
//it iterates through the list of IP's in the subnet
//and checks against all nodes to see if it's taken, until it finds one.
//TODO: We do not handle a case where we run out of addresses.
//We will need to handle that eventually
func UniqueAddress(networkName string) (string, error) {
2021-03-26 00:17:52 +08:00
var network models.Network
network, err := GetParentNetwork(networkName)
if err != nil {
fmt.Println("UniqueAddress encountered an error")
return "666", err
}
2021-03-26 00:17:52 +08:00
offset := true
ip, ipnet, err := net.ParseCIDR(network.AddressRange)
2021-03-26 00:17:52 +08:00
if err != nil {
fmt.Println("UniqueAddress encountered an error")
return "666", err
}
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
if offset {
offset = false
continue
}
if IsIPUnique(networkName, ip.String()) {
2021-03-26 00:17:52 +08:00
return ip.String(), err
}
}
//TODO
err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
2021-03-26 00:17:52 +08:00
return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
}
2021-04-28 11:17:59 +08:00
func UniqueAddress6(networkName string) (string, error) {
2021-05-01 19:57:49 +08:00
var network models.Network
network, err := GetParentNetwork(networkName)
2021-04-28 11:40:01 +08:00
if err != nil {
fmt.Println("Network Not Found")
return "", err
}
2021-05-04 11:01:03 +08:00
if network.IsDualStack == nil || *network.IsDualStack == false {
2021-04-28 11:40:01 +08:00
return "", nil
2021-05-01 19:57:49 +08:00
}
offset := true
ip, ipnet, err := net.ParseCIDR(network.AddressRange6)
if err != nil {
fmt.Println("UniqueAddress6 encountered an error")
return "666", err
}
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
if offset {
offset = false
continue
}
if IsIP6Unique(networkName, ip.String()) {
2021-05-01 19:57:49 +08:00
return ip.String(), err
}
}
//TODO
err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
2021-04-28 11:17:59 +08:00
}
2021-03-26 00:17:52 +08:00
//generate an access key value
func GenKey() string {
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
2021-03-26 00:17:52 +08:00
length := 16
charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
2021-03-26 00:17:52 +08:00
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
2021-03-26 00:17:52 +08:00
}
//generate a key value
//we should probably just have 1 random string generator
//that can be used across all functions
//have a "base string" a "length" and a "charset"
func GenKeyName() string {
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
2021-03-26 00:17:52 +08:00
length := 5
charset := "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
2021-03-26 00:17:52 +08:00
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
2021-05-01 19:57:49 +08:00
return "key" + string(b)
2021-03-26 00:17:52 +08:00
}
//checks if IP is unique in the address range
//used by UniqueAddress
func IsIPUnique(network string, ip string) bool {
2021-03-26 00:17:52 +08:00
var node models.Node
isunique := true
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"address": ip, "network": network}
2021-03-26 00:17:52 +08:00
err := collection.FindOne(ctx, filter).Decode(&node)
2021-03-26 00:17:52 +08:00
defer cancel()
if err != nil {
fmt.Println(err)
return isunique
}
2021-03-26 00:17:52 +08:00
if node.Address == ip {
2021-03-26 00:17:52 +08:00
isunique = false
}
return isunique
}
//checks if IP is unique in the address range
//used by UniqueAddress
func IsIP6Unique(network string, ip string) bool {
var node models.Node
isunique := true
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"address6": ip, "network": network}
err := collection.FindOne(ctx, filter).Decode(&node)
defer cancel()
if err != nil {
fmt.Println(err)
return isunique
}
if node.Address6 == ip {
isunique = false
}
return isunique
}
2021-03-26 00:17:52 +08:00
//called once key has been used by createNode
//reduces value by one and deletes if necessary
func DecrimentKey(networkName string, keyvalue string) {
2021-03-26 00:17:52 +08:00
var network models.Network
2021-03-26 00:17:52 +08:00
network, err := GetParentNetwork(networkName)
if err != nil {
return
}
2021-03-26 00:17:52 +08:00
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
2021-03-26 00:17:52 +08:00
currentkey := network.AccessKeys[i]
if currentkey.Value == keyvalue {
network.AccessKeys[i].Uses--
if network.AccessKeys[i].Uses < 1 {
2021-03-26 00:17:52 +08:00
//this is the part where it will call the delete
//not sure if there's edge cases I'm missing
DeleteKey(network, i)
2021-03-26 00:17:52 +08:00
return
}
}
}
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("networks")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
filter := bson.M{"netid": network.NetID}
2021-03-26 00:17:52 +08:00
update := bson.D{
{"$set", bson.D{
{"accesskeys", network.AccessKeys},
}},
}
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
if errN != nil {
return
}
2021-03-26 00:17:52 +08:00
}
2021-03-26 00:17:52 +08:00
//takes the logic from controllers.deleteKey
func DeleteKey(network models.Network, i int) {
2021-03-26 00:17:52 +08:00
network.AccessKeys = append(network.AccessKeys[:i],
network.AccessKeys[i+1:]...)
2021-03-26 00:17:52 +08:00
collection := mongoconn.Client.Database("netmaker").Collection("networks")
2021-03-26 00:17:52 +08:00
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
2021-03-26 00:17:52 +08:00
// Create filter
filter := bson.M{"netid": network.NetID}
2021-03-26 00:17:52 +08:00
// prepare update model.
update := bson.D{
{"$set", bson.D{
{"accesskeys", network.AccessKeys},
}},
}
2021-03-26 00:17:52 +08:00
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
2021-03-26 00:17:52 +08:00
defer cancel()
2021-03-26 00:17:52 +08:00
if errN != nil {
return
}
2021-03-26 00:17:52 +08:00
}
2021-03-26 00:17:52 +08:00
//increments an IP over the previous
func Inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
2021-03-26 00:17:52 +08:00
ip[j]++
if ip[j] > 0 {
break
}
}
}
2021-05-06 05:24:24 +08:00
func GetAllNodes() ([]models.ReturnNode, error) {
var node models.ReturnNode
var nodes []models.ReturnNode
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// Filter out them ID's again
cur, err := collection.Find(ctx, bson.M{}, options.Find().SetProjection(bson.M{"_id": 0}))
if err != nil {
return []models.ReturnNode{}, err
}
defer cancel()
for cur.Next(context.TODO()) {
err := cur.Decode(&node)
if err != nil {
return []models.ReturnNode{}, err
}
// add node to our array
nodes = append(nodes, node)
}
//TODO: Fatal error
if err := cur.Err(); err != nil {
return []models.ReturnNode{}, err
}
return nodes, nil
}
func GetAllExternals() ([]models.ReturnNode, error) {
var node models.ReturnNode
var nodes []models.ReturnNode
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// Filter out them ID's again
cur, err := collection.Find(ctx, bson.M{}, options.Find().SetProjection(bson.M{"_id": 0}))
if err != nil {
return []models.ReturnNode{}, err
}
defer cancel()
for cur.Next(context.TODO()) {
err := cur.Decode(&node)
if err != nil {
return []models.ReturnNode{}, err
}
// add node to our array
nodes = append(nodes, node)
}
//TODO: Fatal error
if err := cur.Err(); err != nil {
return []models.ReturnNode{}, err
}
return nodes, nil
}