netmaker/functions/helpers.go

448 lines
10 KiB
Go
Raw Normal View History

2021-03-26 00:17:52 +08:00
package functions
import (
2021-07-14 11:08:10 +08:00
"encoding/json"
"fmt"
2021-05-26 00:48:04 +08:00
"log"
"math/rand"
"strings"
"time"
2021-07-21 05:18:45 +08:00
"github.com/gravitl/netmaker/database"
2021-10-27 00:27:29 +08:00
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
2021-05-06 08:41:28 +08:00
"github.com/gravitl/netmaker/servercfg"
2021-03-26 00:17:52 +08:00
)
2021-10-09 03:07:12 +08:00
// PrintUserLog - prints a log with a given username
func PrintUserLog(username string, message string, loglevel int) {
log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
if int32(loglevel) <= servercfg.GetVerbose() && servercfg.GetVerbose() != 0 {
log.Println("[netmaker]", username, message)
}
}
2021-10-09 03:07:12 +08:00
// ParseNetwork - parses a network into a model
2021-07-22 06:55:19 +08:00
func ParseNetwork(value string) (models.Network, error) {
var network models.Network
err := json.Unmarshal([]byte(value), &network)
return network, err
}
2021-10-09 03:07:12 +08:00
// ParseNode - parses a node into a model
2021-07-22 06:55:19 +08:00
func ParseNode(value string) (models.Node, error) {
var node models.Node
err := json.Unmarshal([]byte(value), &node)
return node, err
}
2021-10-09 03:07:12 +08:00
// ParseExtClient - parses an extclient into a model
2021-07-22 06:55:19 +08:00
func ParseExtClient(value string) (models.ExtClient, error) {
var extClient models.ExtClient
err := json.Unmarshal([]byte(value), &extClient)
return extClient, err
}
2021-10-09 03:07:12 +08:00
// ParseIntClient - parses int client
2021-07-22 06:55:19 +08:00
func ParseIntClient(value string) (models.IntClient, error) {
var intClient models.IntClient
err := json.Unmarshal([]byte(value), &intClient)
return intClient, err
}
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
2021-10-09 03:07:12 +08:00
// SliceContains - sees if a slice contains something
2021-07-02 12:03:46 +08:00
func SliceContains(slice []string, item string) bool {
set := make(map[string]struct{}, len(slice))
for _, s := range slice {
set[s] = struct{}{}
}
2021-07-02 12:03:46 +08:00
_, ok := set[item]
return ok
2021-07-02 12:03:46 +08:00
}
2021-10-09 03:07:12 +08:00
// GetPeersList - gets peers for given network
2021-05-26 00:48:04 +08:00
func GetPeersList(networkName string) ([]models.PeersResponse, error) {
var peers []models.PeersResponse
2021-07-21 05:18:45 +08:00
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
if err != nil {
return peers, err
}
2021-05-26 00:48:04 +08:00
2021-07-21 05:18:45 +08:00
for _, value := range collection {
2021-05-26 00:48:04 +08:00
var peer models.PeersResponse
2021-07-21 05:18:45 +08:00
err := json.Unmarshal([]byte(value), &peer)
if err != nil {
2021-07-21 05:18:45 +08:00
continue // try the rest
}
peers = append(peers, peer)
}
2021-05-26 00:48:04 +08:00
return peers, err
2021-05-26 00:48:04 +08:00
}
2021-10-09 03:07:12 +08:00
// GetIntPeersList - get int peers list
2021-05-28 02:54:24 +08:00
func GetIntPeersList() ([]models.PeersResponse, error) {
var peers []models.PeersResponse
2021-07-21 05:18:45 +08:00
records, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
2021-05-28 02:54:24 +08:00
if err != nil {
return peers, err
}
2021-07-21 05:18:45 +08:00
// parse the peers
2021-05-28 02:54:24 +08:00
2021-07-21 05:18:45 +08:00
for _, value := range records {
2021-05-28 02:54:24 +08:00
var peer models.PeersResponse
2021-07-21 05:18:45 +08:00
err := json.Unmarshal([]byte(value), &peer)
if err != nil {
log.Fatal(err)
}
// add the node to our node array
//maybe better to just return this? But then that's just GetNodes...
peers = append(peers, peer)
}
2021-05-28 02:54:24 +08:00
return peers, err
2021-05-28 02:54:24 +08:00
}
2021-10-09 03:07:12 +08:00
// GetServerIntClient - get server int client
2021-07-21 05:18:45 +08:00
func GetServerIntClient() (*models.IntClient, error) {
2021-03-26 00:17:52 +08:00
2021-07-21 05:18:45 +08:00
intClients, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
for _, value := range intClients {
var intClient models.IntClient
err = json.Unmarshal([]byte(value), &intClient)
if err != nil {
return nil, err
}
if intClient.IsServer == "yes" && intClient.Network == "comms" {
return &intClient, nil
}
}
2021-07-21 05:18:45 +08:00
return nil, err
2021-05-28 02:54:24 +08:00
}
2021-10-09 03:07:12 +08:00
// NetworkExists - check if network exists
func NetworkExists(name string) (bool, error) {
2021-03-26 00:17:52 +08:00
2021-07-21 05:18:45 +08:00
var network string
var err error
if network, err = database.FetchRecord(database.NETWORKS_TABLE_NAME, name); err != nil {
return false, err
2021-03-26 00:17:52 +08:00
}
2021-07-21 05:18:45 +08:00
return len(network) > 0, nil
2021-03-26 00:17:52 +08:00
}
2021-10-09 03:07:12 +08:00
// NetworkNodesUpdateAction - updates action of network nodes
2021-08-07 01:39:14 +08:00
func NetworkNodesUpdateAction(networkName string, action string) error {
2021-08-03 06:06:26 +08:00
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
if err != nil {
2021-08-06 03:02:18 +08:00
if database.IsEmptyRecord(err) {
return nil
}
2021-08-03 06:06:26 +08:00
return err
}
for _, value := range collections {
var node models.Node
err := json.Unmarshal([]byte(value), &node)
if err != nil {
fmt.Println("error in node address assignment!")
return err
}
2021-08-10 02:13:19 +08:00
if action == models.NODE_UPDATE_KEY && node.IsStatic == "yes" {
2021-08-10 00:43:09 +08:00
continue
}
2021-08-06 03:02:18 +08:00
if node.Network == networkName {
2021-08-07 01:39:14 +08:00
node.Action = action
2021-08-06 03:02:18 +08:00
data, err := json.Marshal(&node)
if err != nil {
return err
}
node.SetID()
database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
2021-08-03 06:06:26 +08:00
}
2021-08-10 10:31:01 +08:00
}
2021-08-03 06:06:26 +08:00
return nil
}
2021-10-09 03:07:12 +08:00
// NetworkNodesUpdatePullChanges - tells nodes on network to pull
2021-08-07 01:47:39 +08:00
func NetworkNodesUpdatePullChanges(networkName string) error {
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
if err != nil {
if database.IsEmptyRecord(err) {
return nil
}
return err
}
for _, value := range collections {
var node models.Node
err := json.Unmarshal([]byte(value), &node)
if err != nil {
fmt.Println("error in node address assignment!")
return err
}
if node.Network == networkName {
node.PullChanges = "yes"
data, err := json.Marshal(&node)
if err != nil {
return err
}
node.SetID()
database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
}
}
return nil
}
2021-10-09 03:07:12 +08:00
// IsNetworkDisplayNameUnique - checks if network display name unique
func IsNetworkDisplayNameUnique(name string) (bool, error) {
2021-03-26 00:17:52 +08:00
isunique := true
2021-04-13 11:19:01 +08:00
2021-10-27 00:27:29 +08:00
dbs, err := logic.GetNetworks()
if err != nil {
2021-08-06 00:52:50 +08:00
return database.IsEmptyRecord(err), 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
}
2021-10-09 03:07:12 +08:00
// IsMacAddressUnique - checks if mac is unique
2021-07-21 05:18:45 +08:00
func IsMacAddressUnique(macaddress string, networkName string) (bool, error) {
2021-04-13 11:19:01 +08:00
2021-08-06 00:52:50 +08:00
_, err := database.FetchRecord(database.NODES_TABLE_NAME, macaddress+"###"+networkName)
2021-07-21 05:18:45 +08:00
if err != nil {
2021-08-06 00:52:50 +08:00
return database.IsEmptyRecord(err), err
2021-07-21 05:18:45 +08:00
}
2021-04-13 11:19:01 +08:00
2021-07-21 05:18:45 +08:00
return true, nil
}
2021-04-13 11:19:01 +08:00
2021-10-09 03:07:12 +08:00
// GetNetworkNonServerNodeCount - get number of network non server nodes
func GetNetworkNonServerNodeCount(networkName string) (int, error) {
2021-08-06 01:11:21 +08:00
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
count := 0
if err != nil && !database.IsEmptyRecord(err) {
return count, err
}
for _, value := range collection {
var node models.Node
if err = json.Unmarshal([]byte(value), &node); err != nil {
return count, err
} else {
if node.Network == networkName && node.IsServer != "yes" {
2021-08-06 01:11:21 +08:00
count++
}
}
}
return count, nil
}
2021-10-09 03:07:12 +08:00
// IsKeyValidGlobal - checks if a key is valid globally
2021-05-26 00:48:04 +08:00
func IsKeyValidGlobal(keyvalue string) bool {
2021-10-27 00:27:29 +08:00
networks, _ := logic.GetNetworks()
var key models.AccessKey
foundkey := false
isvalid := false
2021-05-26 00:48:04 +08:00
for _, network := range networks {
for i := len(network.AccessKeys) - 1; i >= 0; i-- {
currentkey := network.AccessKeys[i]
if currentkey.Value == keyvalue {
key = currentkey
foundkey = true
2021-05-26 00:48:04 +08:00
break
}
}
if foundkey {
break
}
}
if foundkey {
if key.Uses > 0 {
isvalid = true
}
}
return isvalid
2021-05-26 00:48:04 +08:00
}
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.
2021-10-09 03:07:12 +08:00
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-10-09 03:07:12 +08:00
//This checks to make sure a network name is valid.
2021-03-26 00:17:52 +08:00
//Switch to REGEX?
2021-10-09 03:07:12 +08:00
// NameInNetworkCharSet - see if name is in charset for networks
func NameInNetworkCharSet(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-10-09 03:07:12 +08:00
// NameInDNSCharSet - name in dns char set
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
2021-10-09 03:07:12 +08:00
// NameInNodeCharSet - name in node char set
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
}
2021-10-09 03:07:12 +08:00
// RemoveDeletedNode - remove deleted node
2021-08-10 10:31:01 +08:00
func RemoveDeletedNode(nodeid string) bool {
return database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, nodeid) == nil
}
2021-10-09 03:07:12 +08:00
// DeleteAllIntClients - delete all int clients
2021-05-28 02:54:24 +08:00
func DeleteAllIntClients() error {
2021-07-21 05:18:45 +08:00
err := database.DeleteAllRecords(database.INT_CLIENTS_TABLE_NAME)
if err != nil {
return err
}
return nil
2021-05-28 02:54:24 +08:00
}
2021-10-09 03:07:12 +08:00
// GetAllIntClients - get all int clients
2021-05-28 02:54:24 +08:00
func GetAllIntClients() ([]models.IntClient, error) {
var clients []models.IntClient
2021-07-21 05:18:45 +08:00
collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
if err != nil {
2021-07-21 05:18:45 +08:00
return clients, err
}
2021-07-21 05:18:45 +08:00
for _, value := range collection {
var client models.IntClient
err := json.Unmarshal([]byte(value), &client)
if err != nil {
return []models.IntClient{}, err
}
// add node to our array
clients = append(clients, client)
}
return clients, nil
2021-05-28 02:54:24 +08:00
}
2021-10-09 03:07:12 +08:00
// GetAllExtClients - get all ext clients
2021-05-20 01:59:10 +08:00
func GetAllExtClients() ([]models.ExtClient, error) {
var extclients []models.ExtClient
2021-07-21 05:18:45 +08:00
collection, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
if err != nil {
2021-07-21 05:18:45 +08:00
return extclients, err
}
2021-07-21 05:18:45 +08:00
for _, value := range collection {
var extclient models.ExtClient
err := json.Unmarshal([]byte(value), &extclient)
if err != nil {
return []models.ExtClient{}, err
}
// add node to our array
extclients = append(extclients, extclient)
}
2021-05-20 01:59:10 +08:00
return extclients, nil
}
2021-05-20 01:59:10 +08:00
2021-10-09 03:07:12 +08:00
// GenKey - generates access key
2021-03-26 00:17:52 +08:00
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"
2021-10-09 03:07:12 +08:00
// GenKeyName - generates a key name
2021-03-26 00:17:52 +08:00
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
}
2021-10-09 03:07:12 +08:00
// DeleteKey - deletes a key
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
2021-07-21 05:18:45 +08:00
if networkData, err := json.Marshal(&network); err != nil {
return
2021-07-21 05:18:45 +08:00
} else {
database.Insert(network.NetID, string(networkData), database.NETWORKS_TABLE_NAME)
}
2021-03-26 00:17:52 +08:00
}