Mid way through adopting rqlite

This commit is contained in:
afeiszli
2021-07-21 18:55:19 -04:00
parent d22ad13cfe
commit 93b0b94788
26 changed files with 946 additions and 1587 deletions

View File

@@ -1,25 +1,23 @@
package controller
import (
"context"
"encoding/json"
"io"
"errors"
"fmt"
"math/rand"
"io"
"math/rand"
// "fmt"
"net/http"
"time"
"strconv"
"time"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/database"
"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.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/skip2/go-qrcode"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
func extClientHandlers(r *mux.Router) {
@@ -98,34 +96,22 @@ func getNetworkExtClients(w http.ResponseWriter, r *http.Request) {
func GetNetworkExtClients(network string) ([]models.ExtClient, error) {
var extclients []models.ExtClient
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"network": network}
//Filtering out the ID field cuz Dillon doesn't like it. May want to filter out other fields in the future
cur, err := collection.Find(ctx, filter, options.Find().SetProjection(bson.M{"_id": 0}))
records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
if err != nil {
return []models.ExtClient{}, err
return extclients, err
}
defer cancel()
for cur.Next(context.TODO()) {
//Using a different model for the ReturnExtClient (other than regular extclient).
//Either we should do this for ALL structs (so Networks and Keys)
//OR we should just use the original struct
//My preference is to make some new return structs
//TODO: Think about this. Not an immediate concern. Just need to get some consistency eventually
for _, value := range records {
var extclient models.ExtClient
err := cur.Decode(&extclient)
err = json.Unmarshal([]byte(value), &extclient)
if err != nil {
return []models.ExtClient{}, err
continue
}
if extclient.Network == network {
extclients = append(extclients, extclient)
}
// add item our array of extclients
extclients = append(extclients, extclient)
}
//TODO: Another fatal error we should take care of.
if err := cur.Err(); err != nil {
return []models.ExtClient{}, err
}
return extclients, nil
return extclients, err
}
//A separate function to get all extclients, not just extclients for a particular network.
@@ -149,58 +135,60 @@ func getExtClient(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
var extclient models.ExtClient
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&extclient)
clientid := params["clientid"]
network := params["network"]
client, err := GetExtClient(clientid, network)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
defer cancel()
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(extclient)
json.NewEncoder(w).Encode(client)
}
func GetExtClient(clientid string, network string) (models.ExtClient, error) {
var extclient models.ExtClient
key, err := functions.GetRecordKey(clientid, network)
if err != nil {
return extclient, err
}
data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
if err != nil {
return extclient, err
}
err = json.Unmarshal([]byte(data), &extclient)
return extclient, err
}
//Get an individual extclient. Nothin fancy here folks.
func getExtClientConf(w http.ResponseWriter, r *http.Request) {
// set header.
w.Header().Set("Content-Type", "application/json")
// set header.
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
var extclient models.ExtClient
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&extclient)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
gwnode, err := functions.GetNodeByMacAddress(extclient.Network, extclient.IngressGatewayID)
if err != nil {
fmt.Println("Could not retrieve Ingress Gateway Node " + extclient.IngressGatewayID)
var params = mux.Vars(r)
clientid := params["clientid"]
networkid := params["network"]
client, err := GetExtClient(clientid, networkid)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
return
}
network, err := functions.GetParentNetwork(extclient.Network)
if err != nil {
fmt.Println("Could not retrieve Ingress Gateway Network " + extclient.Network)
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
gwnode, err := functions.GetNodeByMacAddress(client.Network, client.IngressGatewayID)
if err != nil {
fmt.Println("Could not retrieve Ingress Gateway Node " + client.IngressGatewayID)
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
network, err := functions.GetParentNetwork(client.Network)
if err != nil {
fmt.Println("Could not retrieve Ingress Gateway Network " + client.Network)
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
keepalive := ""
if network.DefaultKeepalive != 0 {
keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
@@ -216,12 +204,12 @@ AllowedIPs = %s
Endpoint = %s
%s
`, extclient.Address + "/32",
extclient.PrivateKey,
gwnode.PublicKey,
network.AddressRange,
gwendpoint,
keepalive)
`, client.Address+"/32",
client.PrivateKey,
gwnode.PublicKey,
network.AddressRange,
gwendpoint,
keepalive)
if params["type"] == "qr" {
bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
@@ -240,21 +228,19 @@ Endpoint = %s
}
if params["type"] == "file" {
name := extclient.ClientID + ".conf"
w.Header().Set("Content-Type", "application/config")
w.Header().Set("Content-Disposition", "attachment; filename=\"" + name + "\"")
name := client.ClientID + ".conf"
w.Header().Set("Content-Type", "application/config")
w.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprint(w, config)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
returnErrorResponse(w, r, formatError(err, "internal"))
}
return
}
defer cancel()
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(extclient)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(client)
}
func CreateExtClient(extclient models.ExtClient) error {
@@ -276,25 +262,26 @@ func CreateExtClient(extclient models.ExtClient) error {
extclient.Address = newAddress
}
if extclient.ClientID == "" {
clientid := StringWithCharset(7, charset)
clientname := "client-" + clientid
extclient.ClientID = clientname
}
if extclient.ClientID == "" {
clientid := StringWithCharset(7, charset)
clientname := "client-" + clientid
extclient.ClientID = clientname
}
extclient.LastModified = time.Now().Unix()
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// insert our network into the network table
_, err := collection.InsertOne(ctx, extclient)
defer cancel()
key, err := functions.GetRecordKey(extclient.ClientID, extclient.Network)
if err != nil {
return err
}
data, err := json.Marshal(&extclient)
if err != nil {
return err
}
if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil {
return err
}
err = SetNetworkNodesLastModified(extclient.Network)
return err
}
@@ -322,9 +309,9 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
extclient.IngressGatewayID = macaddress
node, err := functions.GetNodeByMacAddress(networkName, macaddress)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
err = json.NewDecoder(r.Body).Decode(&extclient)
@@ -361,71 +348,49 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
// returnErrorResponse(w, r, formatError(err, "badrequest"))
// return
// }
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&oldExtClient)
key, err := functions.GetRecordKey(params["clientid"], params["network"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
if err = json.Unmarshal([]byte(data), &oldExtClient); err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
newclient, err := UpdateExtClient(newExtClient.ClientID, params["network"], oldExtClient)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
functions.PrintUserLog(r.Header.Get("user"), "updated client "+newExtClient.ClientID, 1)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(newclient)
}
func UpdateExtClient(newclientid string, network string, client models.ExtClient) (models.ExtClient, error) {
//collection := mongoconn.ConnectDB()
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// Create filter
filter := bson.M{"clientid": client.ClientID, "network": network}
// prepare update model.
update := bson.D{
{"$set", bson.D{
{"clientid", newclientid},
}},
}
var clientupdate models.ExtClient
err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&clientupdate)
defer cancel()
return clientupdate, err
err := DeleteExtClient(network, client.ClientID)
if err != nil {
return client, err
}
client.ClientID = newclientid
CreateExtClient(client)
return client, err
}
func DeleteExtClient(network string, clientid string) (bool, error) {
deleted := false
collection := mongoconn.Client.Database("netmaker").Collection("extclients")
filter := bson.M{"network": network, "clientid": clientid}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
result, err := collection.DeleteOne(ctx, filter)
deletecount := result.DeletedCount
if deletecount > 0 {
deleted = true
func DeleteExtClient(network string, clientid string) error {
key, err := functions.GetRecordKey(clientid, network)
if err != nil {
return err
}
defer cancel()
fmt.Println("Deleted extclient client " + clientid + " from network " + network)
return deleted, err
err = database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, key)
return err
}
//Delete a extclient
@@ -437,28 +402,27 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) {
// get params
var params = mux.Vars(r)
success, err := DeleteExtClient(params["network"], params["clientid"])
err := DeleteExtClient(params["network"], params["clientid"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
} else if !success {
err = errors.New("Could not delete extclient " + params["clientid"])
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
functions.PrintUserLog(r.Header.Get("user"),
"Deleted extclient client "+params["clientid"]+" from network "+params["network"], 1)
returnSuccessResponse(w, r, params["clientid"]+" deleted.")
}
func StringWithCharset(length int, charset string) string {
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}
const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
rand.NewSource(time.Now().UnixNano()))