major overhaul initiated

This commit is contained in:
afeiszli
2021-05-25 12:48:04 -04:00
parent 82d430d09e
commit 78ae219b03
37 changed files with 2971 additions and 1754 deletions

View File

@@ -31,6 +31,7 @@ var Config *EnvironmentConfig
type EnvironmentConfig struct { type EnvironmentConfig struct {
Server ServerConfig `yaml:"server"` Server ServerConfig `yaml:"server"`
MongoConn MongoConnConfig `yaml:"mongoconn"` MongoConn MongoConnConfig `yaml:"mongoconn"`
WG WG `yaml:"wg"`
} }
// ServerConfig : // ServerConfig :
@@ -48,6 +49,18 @@ type ServerConfig struct {
DisableRemoteIPCheck string `yaml:"disableremoteipcheck"` DisableRemoteIPCheck string `yaml:"disableremoteipcheck"`
} }
type WG struct {
RegisterKeyRequired string `yaml:"keyrequired"`
GRPCWireGuard string `yaml:"grpcwg"`
GRPCWGInterface string `yaml:"grpciface"`
GRPCWGAddress string `yaml:"grpcaddr"`
GRPCWGAddressRange string `yaml:"grpcaddrrange"`
GRPCWGEndpoint string `yaml:"grpcendpoint"`
GRPCWGPort string `yaml:"grpcport"`
GRPCWGPubKey string `yaml:"pubkey"`
GRPCWGPrivKey string `yaml:"privkey"`
}
type MongoConnConfig struct { type MongoConnConfig struct {
User string `yaml:"user"` User string `yaml:"user"`
Pass string `yaml:"pass"` Pass string `yaml:"pass"`

Binary file not shown.

View File

@@ -58,6 +58,7 @@ func GetPeersList(networkName string) ([]models.PeersResponse, error) {
return peers, err return peers, err
} }
func GetExtPeersList(networkName string, macaddress string) ([]models.ExtPeersResponse, error) { func GetExtPeersList(networkName string, macaddress string) ([]models.ExtPeersResponse, error) {
var peers []models.ExtPeersResponse var peers []models.ExtPeersResponse

View File

@@ -1,233 +0,0 @@
package controller
import (
"context"
"encoding/json"
"errors"
// "fmt"
"net/http"
"time"
"github.com/gorilla/mux"
"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"
// "github.com/skip2/go-qrcode"
)
func externalHandlers(r *mux.Router) {
r.HandleFunc("/api/externals", securityCheck(http.HandlerFunc(getAllExternals))).Methods("GET")
r.HandleFunc("/api/externals/{network}", securityCheck(http.HandlerFunc(getNetworkExternals))).Methods("GET")
r.HandleFunc("/api/externals/{network}/{clientid}", securityCheck(http.HandlerFunc(getExternal))).Methods("GET")
r.HandleFunc("/api/externals/{network}/{clientid}/qr", securityCheck(http.HandlerFunc(getExternal))).Methods("GET")
r.HandleFunc("/api/externals/{network}/{ingressgateway}", securityCheck(http.HandlerFunc(getExternal))).Methods("GET")
r.HandleFunc("/api/externals/{network}/{clientid}", securityCheck(http.HandlerFunc(updateExternal))).Methods("PUT")
r.HandleFunc("/api/externals/{network}/{clientid}", securityCheck(http.HandlerFunc(deleteExternal))).Methods("DELETE")
r.HandleFunc("/api/externals/{network}", securityCheck(http.HandlerFunc(createExternal))).Methods("POST")
}
//Gets all nodes associated with network, including pending nodes
func getNetworkExternals(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var nodes []models.External
var params = mux.Vars(r)
nodes, err := GetNetworkExternals(params["network"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
//Returns all the nodes in JSON format
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(nodes)
}
func GetNetworkExternals(network string) ([]models.External, error) {
var nodes []models.External
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
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}))
if err != nil {
return []models.External{}, err
}
defer cancel()
for cur.Next(context.TODO()) {
//Using a different model for the ReturnExternal (other than regular node).
//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
var node models.External
err := cur.Decode(&node)
if err != nil {
return []models.External{}, err
}
// add item our array of nodes
nodes = append(nodes, node)
}
//TODO: Another fatal error we should take care of.
if err := cur.Err(); err != nil {
return []models.External{}, err
}
return nodes, nil
}
//A separate function to get all nodes, not just nodes for a particular network.
//Not quite sure if this is necessary. Probably necessary based on front end but may want to review after iteration 1 if it's being used or not
func getAllExternals(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
nodes, err := functions.GetAllExternals()
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
//Return all the nodes in JSON format
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(nodes)
}
//Get an individual node. Nothin fancy here folks.
func getExternal(w http.ResponseWriter, r *http.Request) {
// set header.
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
var node models.Node
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"macaddress": params["macaddress"], "network": params["network"]}
err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&node)
defer cancel()
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(node)
}
//This one's a doozy
//To create a node
//Must have valid key and be unique
func createExternal(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
var errorResponse = models.ErrorResponse{
Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
}
networkName := params["network"]
//Check if network exists first
//TODO: This is inefficient. Let's find a better way.
//Just a few rows down we grab the network anyway
networkexists, err := functions.NetworkExists(networkName)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
} else if !networkexists {
errorResponse = models.ErrorResponse{
Code: http.StatusNotFound, Message: "W1R3: Network does not exist! ",
}
returnErrorResponse(w, r, errorResponse)
return
}
var external models.External
//get node from body of request
err = json.NewDecoder(r.Body).Decode(&external)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
err = ValidateExternalCreate(external)
if err != nil {
returnErrorResponse(w, r, formatError(err, "badrequest"))
return
}
node, err = CreateExternal(node, networkName)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(node)
}
func updateExternal(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
//Get id from parameters
//id, _ := primitive.ObjectIDFromHex(params["id"])
var node models.External
//start here
node, err := functions.GetExternalByMacAddress(params["network"], params["macaddress"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
var nodechange models.ExternalUpdate
// we decode our body request params
_ = json.NewDecoder(r.Body).Decode(&nodechange)
if nodechange.Network == "" {
nodechange.Network = node.Network
}
if nodechange.MacAddress == "" {
nodechange.MacAddress = node.MacAddress
}
err = ValidateExternalUpdate(params["network"], nodechange)
if err != nil {
returnErrorResponse(w, r, formatError(err, "badrequest"))
return
}
node, err = UpdateExternal(nodechange, node)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(node)
}
//Delete a node
//Pretty straightforward
func deleteExternal(w http.ResponseWriter, r *http.Request) {
// Set header
w.Header().Set("Content-Type", "application/json")
// get params
var params = mux.Vars(r)
success, err := DeleteExternal(params["macaddress"], params["network"])
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
} else if !success {
err = errors.New("Could not delete node " + params["macaddress"])
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
returnSuccessResponse(w, r, params["macaddress"]+" deleted.")
}

View File

@@ -30,6 +30,7 @@ func networkHandlers(r *mux.Router) {
r.HandleFunc("/api/networks/{networkname}/keyupdate", securityCheck(http.HandlerFunc(keyUpdate))).Methods("POST") r.HandleFunc("/api/networks/{networkname}/keyupdate", securityCheck(http.HandlerFunc(keyUpdate))).Methods("POST")
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(http.HandlerFunc(createAccessKey))).Methods("POST") r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(http.HandlerFunc(createAccessKey))).Methods("POST")
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(http.HandlerFunc(getAccessKeys))).Methods("GET") r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(http.HandlerFunc(getAccessKeys))).Methods("GET")
r.HandleFunc("/api/networks/{networkname}/signuptoken", securityCheck(http.HandlerFunc(getSignupToken))).Methods("GET")
r.HandleFunc("/api/networks/{networkname}/keys/{name}", securityCheck(http.HandlerFunc(deleteAccessKey))).Methods("DELETE") r.HandleFunc("/api/networks/{networkname}/keys/{name}", securityCheck(http.HandlerFunc(deleteAccessKey))).Methods("DELETE")
} }
@@ -640,6 +641,31 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
return accesskey, nil return accesskey, nil
} }
func GetSignupToken(netID string) (models.AccessKey, error) {
var accesskey models.AccessKey
address := servercfg.GetGRPCHost() + ":" + servercfg.GetGRPCPort()
accessstringdec := address + "|" + netID + "|" + "" + "|"
accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
return accesskey, nil
}
func getSignupToken(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
netID := params["networkname"]
token, err := GetSignupToken(netID)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(token)
}
//pretty simple get //pretty simple get
func getAccessKeys(w http.ResponseWriter, r *http.Request) { func getAccessKeys(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@@ -73,6 +73,57 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe
return response, nil return response, nil
} }
func (s *NodeServiceServer) GetConn(ctx context.Context, data *nodepb.Client) (*nodepb.Client, error) {
// Get the protobuf node type from the protobuf request type
// Essentially doing req.Node to access the struct with a nil check
// Now we have to convert this into a NodeItem type to convert into BSON
clientreq := models.ServerClient{
// ID: primitive.NilObjectID,
Address: data.GetAddress(),
Address6: data.GetAddress6(),
AccessKey: data.GetAccesskey(),
PublicKey: data.GetPublickey(),
PrivateKey: data.GetPrivatekey(),
ServerPort: data.GetServerport(),
ServerKey: data.GetServerkey(),
ServerEndpoint: data.GetServerendpoint(),
}
//Check to see if key is valid
//TODO: Triple inefficient!!! This is the third call to the DB we make for networks
if servercfg.IsRegisterKeyRequired() {
validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
if !validKey {
return nil, status.Errorf(
codes.Internal,
fmt.Sprintf("Invalid key, and server does not allow no-key signups"),
)
}
}
client, err := RegisterClient(clientreq)
if err != nil {
// return internal gRPC error to be handled later
return nil, status.Errorf(
codes.Internal,
fmt.Sprintf("Internal error: %v", err),
)
}
// return the node in a CreateNodeRes type
response := &nodepb.Client{
Privatekey: client.PrivateKey,
Publickey: client.PublicKey,
Accesskey: client.AccessKey,
Address: client.Address,
Address6: client.Address6,
Serverendpoint: client.ServerEndpoint,
Serverport: client.ServerPort,
Serverkey: client.ServerKey,
}
return response, nil
}
func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNodeReq) (*nodepb.CreateNodeRes, error) { func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNodeReq) (*nodepb.CreateNodeRes, error) {
// Get the protobuf node type from the protobuf request type // Get the protobuf node type from the protobuf request type
// Essentially doing req.Node to access the struct with a nil check // Essentially doing req.Node to access the struct with a nil check

View File

@@ -32,6 +32,7 @@ func nodeHandlers(r *mux.Router) {
r.HandleFunc("/api/nodes/{network}/{macaddress}/deleteingress", securityCheck(http.HandlerFunc(deleteIngressGateway))).Methods("DELETE") r.HandleFunc("/api/nodes/{network}/{macaddress}/deleteingress", securityCheck(http.HandlerFunc(deleteIngressGateway))).Methods("DELETE")
r.HandleFunc("/api/nodes/{network}/{macaddress}/approve", authorize(true, "master", http.HandlerFunc(uncordonNode))).Methods("POST") r.HandleFunc("/api/nodes/{network}/{macaddress}/approve", authorize(true, "master", http.HandlerFunc(uncordonNode))).Methods("POST")
r.HandleFunc("/api/nodes/{network}", createNode).Methods("POST") r.HandleFunc("/api/nodes/{network}", createNode).Methods("POST")
//r.HandleFunc("/api/register", registerClient).Methods("POST")
r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET") r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET")
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST") r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST")

194
controllers/serverClient.go Normal file
View File

@@ -0,0 +1,194 @@
package controller
import (
"context"
"encoding/json"
"fmt"
// "fmt"
"net/http"
"time"
"strconv"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/functions"
"github.com/gravitl/netmaker/serverctl"
"github.com/gravitl/netmaker/servercfg"
"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"
)
func serverClientHandlers(r *mux.Router) {
r.HandleFunc("/api/wgconf/{macaddress}", securityCheck(http.HandlerFunc(getWGClientConf))).Methods("GET")
r.HandleFunc("/api/register", securityCheck(http.HandlerFunc(registerClient))).Methods("POST")
}
//Get an individual extclient. Nothin fancy here folks.
func getWGClientConf(w http.ResponseWriter, r *http.Request) {
// 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": "grpc", "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)
returnErrorResponse(w, r, formatError(err, "internal"))
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
}
keepalive := ""
if network.DefaultKeepalive != 0 {
keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
}
gwendpoint := gwnode.Endpoint + ":" + strconv.Itoa(int(gwnode.ListenPort))
config := fmt.Sprintf(`[Interface]
Address = %s
PrivateKey = %s
[Peer]
PublicKey = %s
AllowedIPs = %s
Endpoint = %s
%s
`, extclient.Address + "/32",
extclient.PrivateKey,
gwnode.PublicKey,
network.AddressRange,
gwendpoint,
keepalive)
if params["type"] == "qr" {
bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.Header().Set("Content-Type", "image/png")
w.WriteHeader(http.StatusOK)
_, err = w.Write(bytes)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
return
}
if params["type"] == "file" {
name := extclient.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"))
}
return
}
defer cancel()
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(extclient)
}
func RegisterClient(client models.ServerClient) (models.ServerClient, error) {
if client.PrivateKey == "" {
privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil {
return client, err
}
client.PrivateKey = privateKey.String()
client.PublicKey = privateKey.PublicKey().String()
}
if client.Address == "" {
newAddress, err := functions.UniqueAddress6(client.Network)
if err != nil {
return client, err
}
client.Address6 = newAddress
}
if client.Network == "" { client.Network = "comms" }
server, err := serverctl.GetServerWGConf()
if err != nil {
return client, err
}
client.ServerEndpoint = server.ServerEndpoint
client.ServerPort = server.ServerPort
client.ServerKey = server.ServerKey
collection := mongoconn.Client.Database("netmaker").Collection("serverclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// insert our network into the network table
_, err = collection.InsertOne(ctx, client)
defer cancel()
if err != nil {
return client, err
}
err = serverctl.ReconfigureServerWireGuard()
return client, err
}
func registerClient(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var errorResponse = models.ErrorResponse{
Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
}
var clientreq models.ServerClient
//get node from body of request
err := json.NewDecoder(r.Body).Decode(&clientreq)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
if servercfg.IsRegisterKeyRequired() {
validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
if !validKey {
errorResponse = models.ErrorResponse{
Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
}
returnErrorResponse(w, r, errorResponse)
return
}
}
client, err := RegisterClient(clientreq)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(client)
}

View File

@@ -9,11 +9,11 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"log"
"math/rand" "math/rand"
"net" "net"
"strings" "strings"
"time" "time"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn" "github.com/gravitl/netmaker/mongoconn"
"github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/servercfg"
@@ -81,6 +81,48 @@ func CreateServerToken(netID string) (string, error) {
return accesskey.AccessString, nil return accesskey.AccessString, nil
} }
func GetPeersList(networkName string) ([]models.PeersResponse, error) {
var peers []models.PeersResponse
//Connection mongoDB with mongoconn class
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
//Get all nodes in the relevant network which are NOT in pending state
filter := bson.M{"network": networkName, "ispending": false}
cur, err := collection.Find(ctx, filter)
if err != nil {
return peers, err
}
// Close the cursor once finished and cancel if it takes too long
defer cancel()
for cur.Next(context.TODO()) {
var peer models.PeersResponse
err := cur.Decode(&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)
}
//Uh oh, fatal error! This needs some better error handling
//TODO: needs appropriate error handling so the server doesnt shut down.
if err := cur.Err(); err != nil {
log.Fatal(err)
}
return peers, err
}
func IsFieldUnique(network string, field string, value string) bool { func IsFieldUnique(network string, field string, value string) bool {
var node models.Node var node models.Node
@@ -344,6 +386,31 @@ func IsKeyValid(networkname string, keyvalue string) bool {
return isvalid return isvalid
} }
func IsKeyValidGlobal(keyvalue string) bool {
networks, _ := ListNetworks()
var key models.AccessKey
foundkey := false
isvalid := false
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
break
}
}
if foundkey { break }
}
if foundkey {
if key.Uses > 0 {
isvalid = true
}
}
return isvalid
}
//TODO: Contains a fatal error return. Need to change //TODO: Contains a fatal error return. Need to change
//This just gets a network object from a network name //This just gets a network object from a network name
//Should probably just be GetNetwork. kind of a dumb name. //Should probably just be GetNetwork. kind of a dumb name.

4
go.mod
View File

@@ -3,6 +3,7 @@ module github.com/gravitl/netmaker
go 1.15 go 1.15
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-playground/validator/v10 v10.5.0 github.com/go-playground/validator/v10 v10.5.0
github.com/golang/protobuf v1.4.3 // indirect github.com/golang/protobuf v1.4.3 // indirect
@@ -11,6 +12,9 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/txn2/txeh v1.3.0 github.com/txn2/txeh v1.3.0
github.com/urfave/cli v1.22.5 // indirect
github.com/urfave/cli/v2 v2.3.0 // indirect
github.com/vishvananda/netlink v1.1.0 // indirect
go.mongodb.org/mongo-driver v1.4.3 go.mongodb.org/mongo-driver v1.4.3
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect

18
go.sum
View File

@@ -9,7 +9,10 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -133,7 +136,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -159,6 +167,14 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E= github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E=
github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8= github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
@@ -210,6 +226,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -268,6 +285,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

View File

@@ -646,6 +646,101 @@ func (m *ExtPeersResponse) GetKeepalive() int32 {
return 0 return 0
} }
type Client struct {
Privatekey string `protobuf:"bytes,1,opt,name=privatekey,proto3" json:"privatekey,omitempty"`
Publickey string `protobuf:"bytes,2,opt,name=publickey,proto3" json:"publickey,omitempty"`
Accesskey string `protobuf:"bytes,3,opt,name=accesskey,proto3" json:"accesskey,omitempty"`
Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"`
Address6 string `protobuf:"bytes,5,opt,name=address6,proto3" json:"address6,omitempty"`
Serverendpoint string `protobuf:"bytes,6,opt,name=serverendpoint,proto3" json:"serverendpoint,omitempty"`
Serverport string `protobuf:"bytes,7,opt,name=serverport,proto3" json:"serverport,omitempty"`
Serverkey string `protobuf:"bytes,8,opt,name=serverkey,proto3" json:"serverkey,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Client) Reset() { *m = Client{} }
func (m *Client) String() string { return proto.CompactTextString(m) }
func (*Client) ProtoMessage() {}
func (*Client) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{6}
}
func (m *Client) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Client.Unmarshal(m, b)
}
func (m *Client) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Client.Marshal(b, m, deterministic)
}
func (m *Client) XXX_Merge(src proto.Message) {
xxx_messageInfo_Client.Merge(m, src)
}
func (m *Client) XXX_Size() int {
return xxx_messageInfo_Client.Size(m)
}
func (m *Client) XXX_DiscardUnknown() {
xxx_messageInfo_Client.DiscardUnknown(m)
}
var xxx_messageInfo_Client proto.InternalMessageInfo
func (m *Client) GetPrivatekey() string {
if m != nil {
return m.Privatekey
}
return ""
}
func (m *Client) GetPublickey() string {
if m != nil {
return m.Publickey
}
return ""
}
func (m *Client) GetAccesskey() string {
if m != nil {
return m.Accesskey
}
return ""
}
func (m *Client) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
func (m *Client) GetAddress6() string {
if m != nil {
return m.Address6
}
return ""
}
func (m *Client) GetServerendpoint() string {
if m != nil {
return m.Serverendpoint
}
return ""
}
func (m *Client) GetServerport() string {
if m != nil {
return m.Serverport
}
return ""
}
func (m *Client) GetServerkey() string {
if m != nil {
return m.Serverkey
}
return ""
}
type CreateNodeReq struct { type CreateNodeReq struct {
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -657,7 +752,7 @@ func (m *CreateNodeReq) Reset() { *m = CreateNodeReq{} }
func (m *CreateNodeReq) String() string { return proto.CompactTextString(m) } func (m *CreateNodeReq) String() string { return proto.CompactTextString(m) }
func (*CreateNodeReq) ProtoMessage() {} func (*CreateNodeReq) ProtoMessage() {}
func (*CreateNodeReq) Descriptor() ([]byte, []int) { func (*CreateNodeReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{6} return fileDescriptor_d13bd996b67da4ef, []int{7}
} }
func (m *CreateNodeReq) XXX_Unmarshal(b []byte) error { func (m *CreateNodeReq) XXX_Unmarshal(b []byte) error {
@@ -696,7 +791,7 @@ func (m *CreateNodeRes) Reset() { *m = CreateNodeRes{} }
func (m *CreateNodeRes) String() string { return proto.CompactTextString(m) } func (m *CreateNodeRes) String() string { return proto.CompactTextString(m) }
func (*CreateNodeRes) ProtoMessage() {} func (*CreateNodeRes) ProtoMessage() {}
func (*CreateNodeRes) Descriptor() ([]byte, []int) { func (*CreateNodeRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{7} return fileDescriptor_d13bd996b67da4ef, []int{8}
} }
func (m *CreateNodeRes) XXX_Unmarshal(b []byte) error { func (m *CreateNodeRes) XXX_Unmarshal(b []byte) error {
@@ -735,7 +830,7 @@ func (m *UpdateNodeReq) Reset() { *m = UpdateNodeReq{} }
func (m *UpdateNodeReq) String() string { return proto.CompactTextString(m) } func (m *UpdateNodeReq) String() string { return proto.CompactTextString(m) }
func (*UpdateNodeReq) ProtoMessage() {} func (*UpdateNodeReq) ProtoMessage() {}
func (*UpdateNodeReq) Descriptor() ([]byte, []int) { func (*UpdateNodeReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{8} return fileDescriptor_d13bd996b67da4ef, []int{9}
} }
func (m *UpdateNodeReq) XXX_Unmarshal(b []byte) error { func (m *UpdateNodeReq) XXX_Unmarshal(b []byte) error {
@@ -774,7 +869,7 @@ func (m *UpdateNodeRes) Reset() { *m = UpdateNodeRes{} }
func (m *UpdateNodeRes) String() string { return proto.CompactTextString(m) } func (m *UpdateNodeRes) String() string { return proto.CompactTextString(m) }
func (*UpdateNodeRes) ProtoMessage() {} func (*UpdateNodeRes) ProtoMessage() {}
func (*UpdateNodeRes) Descriptor() ([]byte, []int) { func (*UpdateNodeRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{9} return fileDescriptor_d13bd996b67da4ef, []int{10}
} }
func (m *UpdateNodeRes) XXX_Unmarshal(b []byte) error { func (m *UpdateNodeRes) XXX_Unmarshal(b []byte) error {
@@ -814,7 +909,7 @@ func (m *ReadNodeReq) Reset() { *m = ReadNodeReq{} }
func (m *ReadNodeReq) String() string { return proto.CompactTextString(m) } func (m *ReadNodeReq) String() string { return proto.CompactTextString(m) }
func (*ReadNodeReq) ProtoMessage() {} func (*ReadNodeReq) ProtoMessage() {}
func (*ReadNodeReq) Descriptor() ([]byte, []int) { func (*ReadNodeReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{10} return fileDescriptor_d13bd996b67da4ef, []int{11}
} }
func (m *ReadNodeReq) XXX_Unmarshal(b []byte) error { func (m *ReadNodeReq) XXX_Unmarshal(b []byte) error {
@@ -860,7 +955,7 @@ func (m *ReadNodeRes) Reset() { *m = ReadNodeRes{} }
func (m *ReadNodeRes) String() string { return proto.CompactTextString(m) } func (m *ReadNodeRes) String() string { return proto.CompactTextString(m) }
func (*ReadNodeRes) ProtoMessage() {} func (*ReadNodeRes) ProtoMessage() {}
func (*ReadNodeRes) Descriptor() ([]byte, []int) { func (*ReadNodeRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{11} return fileDescriptor_d13bd996b67da4ef, []int{12}
} }
func (m *ReadNodeRes) XXX_Unmarshal(b []byte) error { func (m *ReadNodeRes) XXX_Unmarshal(b []byte) error {
@@ -900,7 +995,7 @@ func (m *DeleteNodeReq) Reset() { *m = DeleteNodeReq{} }
func (m *DeleteNodeReq) String() string { return proto.CompactTextString(m) } func (m *DeleteNodeReq) String() string { return proto.CompactTextString(m) }
func (*DeleteNodeReq) ProtoMessage() {} func (*DeleteNodeReq) ProtoMessage() {}
func (*DeleteNodeReq) Descriptor() ([]byte, []int) { func (*DeleteNodeReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{12} return fileDescriptor_d13bd996b67da4ef, []int{13}
} }
func (m *DeleteNodeReq) XXX_Unmarshal(b []byte) error { func (m *DeleteNodeReq) XXX_Unmarshal(b []byte) error {
@@ -946,7 +1041,7 @@ func (m *DeleteNodeRes) Reset() { *m = DeleteNodeRes{} }
func (m *DeleteNodeRes) String() string { return proto.CompactTextString(m) } func (m *DeleteNodeRes) String() string { return proto.CompactTextString(m) }
func (*DeleteNodeRes) ProtoMessage() {} func (*DeleteNodeRes) ProtoMessage() {}
func (*DeleteNodeRes) Descriptor() ([]byte, []int) { func (*DeleteNodeRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{13} return fileDescriptor_d13bd996b67da4ef, []int{14}
} }
func (m *DeleteNodeRes) XXX_Unmarshal(b []byte) error { func (m *DeleteNodeRes) XXX_Unmarshal(b []byte) error {
@@ -986,7 +1081,7 @@ func (m *GetPeersReq) Reset() { *m = GetPeersReq{} }
func (m *GetPeersReq) String() string { return proto.CompactTextString(m) } func (m *GetPeersReq) String() string { return proto.CompactTextString(m) }
func (*GetPeersReq) ProtoMessage() {} func (*GetPeersReq) ProtoMessage() {}
func (*GetPeersReq) Descriptor() ([]byte, []int) { func (*GetPeersReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{14} return fileDescriptor_d13bd996b67da4ef, []int{15}
} }
func (m *GetPeersReq) XXX_Unmarshal(b []byte) error { func (m *GetPeersReq) XXX_Unmarshal(b []byte) error {
@@ -1033,7 +1128,7 @@ func (m *GetExtPeersReq) Reset() { *m = GetExtPeersReq{} }
func (m *GetExtPeersReq) String() string { return proto.CompactTextString(m) } func (m *GetExtPeersReq) String() string { return proto.CompactTextString(m) }
func (*GetExtPeersReq) ProtoMessage() {} func (*GetExtPeersReq) ProtoMessage() {}
func (*GetExtPeersReq) Descriptor() ([]byte, []int) { func (*GetExtPeersReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{15} return fileDescriptor_d13bd996b67da4ef, []int{16}
} }
func (m *GetExtPeersReq) XXX_Unmarshal(b []byte) error { func (m *GetExtPeersReq) XXX_Unmarshal(b []byte) error {
@@ -1079,7 +1174,7 @@ func (m *GetPeersRes) Reset() { *m = GetPeersRes{} }
func (m *GetPeersRes) String() string { return proto.CompactTextString(m) } func (m *GetPeersRes) String() string { return proto.CompactTextString(m) }
func (*GetPeersRes) ProtoMessage() {} func (*GetPeersRes) ProtoMessage() {}
func (*GetPeersRes) Descriptor() ([]byte, []int) { func (*GetPeersRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{16} return fileDescriptor_d13bd996b67da4ef, []int{17}
} }
func (m *GetPeersRes) XXX_Unmarshal(b []byte) error { func (m *GetPeersRes) XXX_Unmarshal(b []byte) error {
@@ -1118,7 +1213,7 @@ func (m *GetExtPeersRes) Reset() { *m = GetExtPeersRes{} }
func (m *GetExtPeersRes) String() string { return proto.CompactTextString(m) } func (m *GetExtPeersRes) String() string { return proto.CompactTextString(m) }
func (*GetExtPeersRes) ProtoMessage() {} func (*GetExtPeersRes) ProtoMessage() {}
func (*GetExtPeersRes) Descriptor() ([]byte, []int) { func (*GetExtPeersRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{17} return fileDescriptor_d13bd996b67da4ef, []int{18}
} }
func (m *GetExtPeersRes) XXX_Unmarshal(b []byte) error { func (m *GetExtPeersRes) XXX_Unmarshal(b []byte) error {
@@ -1157,7 +1252,7 @@ func (m *CheckInReq) Reset() { *m = CheckInReq{} }
func (m *CheckInReq) String() string { return proto.CompactTextString(m) } func (m *CheckInReq) String() string { return proto.CompactTextString(m) }
func (*CheckInReq) ProtoMessage() {} func (*CheckInReq) ProtoMessage() {}
func (*CheckInReq) Descriptor() ([]byte, []int) { func (*CheckInReq) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{18} return fileDescriptor_d13bd996b67da4ef, []int{19}
} }
func (m *CheckInReq) XXX_Unmarshal(b []byte) error { func (m *CheckInReq) XXX_Unmarshal(b []byte) error {
@@ -1196,7 +1291,7 @@ func (m *CheckInRes) Reset() { *m = CheckInRes{} }
func (m *CheckInRes) String() string { return proto.CompactTextString(m) } func (m *CheckInRes) String() string { return proto.CompactTextString(m) }
func (*CheckInRes) ProtoMessage() {} func (*CheckInRes) ProtoMessage() {}
func (*CheckInRes) Descriptor() ([]byte, []int) { func (*CheckInRes) Descriptor() ([]byte, []int) {
return fileDescriptor_d13bd996b67da4ef, []int{19} return fileDescriptor_d13bd996b67da4ef, []int{20}
} }
func (m *CheckInRes) XXX_Unmarshal(b []byte) error { func (m *CheckInRes) XXX_Unmarshal(b []byte) error {
@@ -1231,6 +1326,7 @@ func init() {
proto.RegisterType((*CheckInResponse)(nil), "node.CheckInResponse") proto.RegisterType((*CheckInResponse)(nil), "node.CheckInResponse")
proto.RegisterType((*PeersResponse)(nil), "node.PeersResponse") proto.RegisterType((*PeersResponse)(nil), "node.PeersResponse")
proto.RegisterType((*ExtPeersResponse)(nil), "node.ExtPeersResponse") proto.RegisterType((*ExtPeersResponse)(nil), "node.ExtPeersResponse")
proto.RegisterType((*Client)(nil), "node.Client")
proto.RegisterType((*CreateNodeReq)(nil), "node.CreateNodeReq") proto.RegisterType((*CreateNodeReq)(nil), "node.CreateNodeReq")
proto.RegisterType((*CreateNodeRes)(nil), "node.CreateNodeRes") proto.RegisterType((*CreateNodeRes)(nil), "node.CreateNodeRes")
proto.RegisterType((*UpdateNodeReq)(nil), "node.UpdateNodeReq") proto.RegisterType((*UpdateNodeReq)(nil), "node.UpdateNodeReq")
@@ -1250,69 +1346,74 @@ func init() {
func init() { proto.RegisterFile("grpc/node.proto", fileDescriptor_d13bd996b67da4ef) } func init() { proto.RegisterFile("grpc/node.proto", fileDescriptor_d13bd996b67da4ef) }
var fileDescriptor_d13bd996b67da4ef = []byte{ var fileDescriptor_d13bd996b67da4ef = []byte{
// 1020 bytes of a gzipped FileDescriptorProto // 1093 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0xdb, 0x6e, 0x1b, 0xc5, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0x4d, 0x6f, 0x1b, 0x45,
0x1b, 0x97, 0x9d, 0x93, 0xf3, 0x39, 0x4e, 0xd2, 0x49, 0x9b, 0xff, 0xfc, 0x4d, 0x55, 0x45, 0x16, 0x18, 0x96, 0x9d, 0xd8, 0x71, 0x5f, 0xd7, 0x49, 0x3a, 0x6d, 0xc3, 0x60, 0xaa, 0x2a, 0x5a, 0xa1,
0x42, 0x29, 0x22, 0x76, 0x08, 0x52, 0x85, 0xc4, 0x05, 0x12, 0x2d, 0x8a, 0x40, 0x50, 0xc1, 0x22, 0x2a, 0x45, 0x24, 0x0e, 0x41, 0xaa, 0x90, 0x38, 0x20, 0x91, 0xa2, 0x08, 0x04, 0x15, 0x2c, 0xe2,
0x6e, 0xb8, 0x9b, 0xec, 0x7c, 0xde, 0x8e, 0xbc, 0x99, 0xd9, 0xec, 0x8c, 0xe3, 0xe6, 0x01, 0x78, 0xc2, 0x6d, 0xb2, 0xfb, 0x7a, 0x3b, 0xf2, 0x66, 0x66, 0xb3, 0x33, 0xb6, 0x9b, 0x1b, 0x17, 0x7e,
0x28, 0xc4, 0x9b, 0x70, 0xcd, 0x83, 0xa0, 0x39, 0xac, 0x77, 0x76, 0x63, 0x92, 0x54, 0xb9, 0xe3, 0x14, 0xe2, 0x9f, 0x70, 0xe6, 0x87, 0xa0, 0xf9, 0x58, 0xef, 0xec, 0xc6, 0x4d, 0x52, 0xe5, 0xc6,
0x6e, 0xbf, 0xdf, 0x7c, 0xe7, 0xa3, 0x0d, 0x7b, 0x59, 0x59, 0xa4, 0x13, 0xa9, 0x38, 0x8e, 0x8b, 0xcd, 0xf3, 0xcc, 0xfb, 0xf9, 0xbc, 0x1f, 0x3b, 0x86, 0x9d, 0xac, 0x2c, 0x92, 0x89, 0x90, 0x29,
0x52, 0x19, 0x45, 0xd6, 0xed, 0xf7, 0x88, 0xc3, 0xce, 0x0f, 0x2a, 0x13, 0x32, 0xc1, 0xab, 0x39, 0x1e, 0x15, 0xa5, 0xd4, 0x92, 0x6c, 0x9a, 0xdf, 0x51, 0x0a, 0x0f, 0x7f, 0x94, 0x19, 0x17, 0x31,
0x6a, 0x43, 0x5e, 0x00, 0x5c, 0xb2, 0x94, 0x71, 0x5e, 0xa2, 0xd6, 0xb4, 0x73, 0xd4, 0x39, 0xde, 0x5e, 0xce, 0x51, 0x69, 0xf2, 0x1c, 0xe0, 0x82, 0x25, 0x2c, 0x4d, 0x4b, 0x54, 0x8a, 0x76, 0xf6,
0x4e, 0x22, 0x84, 0x0c, 0xa1, 0x57, 0x30, 0xad, 0x17, 0xaa, 0xe4, 0xb4, 0xeb, 0x5e, 0x97, 0x34, 0x3b, 0x07, 0x0f, 0xe2, 0x00, 0x21, 0x63, 0x18, 0x14, 0x4c, 0xa9, 0xa5, 0x2c, 0x53, 0xda, 0xb5,
0xa1, 0xb0, 0x25, 0xd1, 0x2c, 0x54, 0x39, 0xa3, 0x6b, 0xee, 0xa9, 0x22, 0x47, 0x9f, 0xc3, 0x20, 0xb7, 0xab, 0x33, 0xa1, 0xb0, 0x25, 0x50, 0x2f, 0x65, 0x39, 0xa3, 0x1b, 0xf6, 0xaa, 0x3a, 0x46,
0x58, 0xd1, 0x85, 0x92, 0x1a, 0xc9, 0x11, 0xf4, 0x59, 0x9a, 0xa2, 0xd6, 0x46, 0xcd, 0x50, 0x06, 0x5f, 0xc0, 0xc8, 0x7b, 0x51, 0x85, 0x14, 0x0a, 0xc9, 0x3e, 0x0c, 0x59, 0x92, 0xa0, 0x52, 0x5a,
0x3b, 0x31, 0x34, 0xfa, 0x6b, 0x13, 0xd6, 0xdf, 0x2a, 0x8e, 0x64, 0x17, 0xba, 0x82, 0x07, 0x8e, 0xce, 0x50, 0x78, 0x3f, 0x21, 0x14, 0xfd, 0xd3, 0x87, 0xcd, 0x37, 0x32, 0x45, 0xb2, 0x0d, 0x5d,
0xae, 0xe0, 0x84, 0xc0, 0xba, 0x64, 0x97, 0x18, 0xac, 0xbb, 0x6f, 0x6b, 0xb9, 0x72, 0x39, 0x58, 0x9e, 0x7a, 0x89, 0x2e, 0x4f, 0x09, 0x81, 0x4d, 0xc1, 0x2e, 0xd0, 0x7b, 0xb7, 0xbf, 0x8d, 0xe7,
0x8e, 0xfc, 0x0d, 0x9f, 0xaf, 0xe8, 0xd0, 0xfb, 0x5b, 0xd1, 0x36, 0xd6, 0x5c, 0x68, 0x83, 0xb2, 0x2a, 0x64, 0xef, 0x39, 0x88, 0xd7, 0xff, 0x7c, 0x45, 0xc7, 0x2e, 0xde, 0xea, 0x6c, 0x72, 0xcd,
0x50, 0xa5, 0xa1, 0xeb, 0x47, 0x9d, 0xe3, 0x8d, 0x24, 0x42, 0xc8, 0x73, 0xd8, 0x2e, 0xe6, 0x17, 0xb9, 0xd2, 0x28, 0x0a, 0x59, 0x6a, 0xba, 0xb9, 0xdf, 0x39, 0xe8, 0xc5, 0x01, 0x42, 0x9e, 0xc1,
0xb9, 0x48, 0x67, 0x78, 0x43, 0x37, 0x9c, 0x70, 0x0d, 0x58, 0xcd, 0x28, 0x79, 0xa1, 0x84, 0x34, 0x83, 0x62, 0x7e, 0x9e, 0xf3, 0x64, 0x86, 0x57, 0xb4, 0x67, 0x95, 0x6b, 0xc0, 0x58, 0x46, 0x91,
0x74, 0xd3, 0x6b, 0xae, 0xe8, 0x56, 0x16, 0xb7, 0xee, 0xcc, 0x62, 0xaf, 0x95, 0xc5, 0x23, 0xe8, 0x16, 0x92, 0x0b, 0x4d, 0xfb, 0xce, 0x72, 0x75, 0x6e, 0xb1, 0xb8, 0x75, 0x23, 0x8b, 0x83, 0x16,
0xdb, 0xca, 0x54, 0x99, 0xdc, 0xf6, 0xa9, 0x89, 0x20, 0xeb, 0x97, 0xd0, 0x05, 0x4a, 0x2e, 0x64, 0x8b, 0xfb, 0x30, 0x34, 0x95, 0xa9, 0x98, 0x7c, 0xe0, 0xa8, 0x09, 0x20, 0x13, 0x17, 0x57, 0x05,
0x46, 0xe1, 0xa8, 0x73, 0xdc, 0x4b, 0x6a, 0x80, 0x1c, 0xc2, 0x66, 0xa1, 0xb4, 0x99, 0x17, 0xb4, 0x8a, 0x94, 0x8b, 0x8c, 0xc2, 0x7e, 0xe7, 0x60, 0x10, 0xd7, 0x00, 0xd9, 0x83, 0x7e, 0x21, 0x95,
0xef, 0x44, 0x03, 0xe5, 0x6c, 0x2a, 0x6d, 0xb8, 0x5a, 0x48, 0xba, 0x13, 0x6c, 0x06, 0xda, 0x6a, 0x9e, 0x17, 0x74, 0x68, 0x55, 0xfd, 0xc9, 0xfa, 0x94, 0x4a, 0xa7, 0x72, 0x29, 0xe8, 0x43, 0xef,
0x9c, 0x21, 0x16, 0x2c, 0x17, 0xd7, 0x48, 0x07, 0x2e, 0x11, 0x35, 0x60, 0xa3, 0xd1, 0xec, 0x1a, 0xd3, 0x9f, 0x8d, 0xc5, 0x19, 0x62, 0xc1, 0x72, 0xbe, 0x40, 0x3a, 0xb2, 0x44, 0xd4, 0x80, 0xc9,
0x53, 0x25, 0xa7, 0x22, 0xa3, 0xbb, 0xce, 0x60, 0x84, 0x58, 0x69, 0x5f, 0x39, 0x9b, 0xa7, 0x3d, 0x46, 0xb1, 0x05, 0x26, 0x52, 0x4c, 0x79, 0x46, 0xb7, 0xad, 0xc3, 0x00, 0x31, 0xda, 0xae, 0x72,
0x9f, 0xa7, 0x25, 0xe0, 0xbc, 0x95, 0x06, 0xcb, 0x29, 0x4b, 0x91, 0xee, 0xfb, 0xd7, 0x25, 0x60, 0x86, 0xa7, 0x1d, 0xc7, 0xd3, 0x0a, 0xb0, 0xd1, 0x0a, 0x8d, 0xe5, 0x94, 0x25, 0x48, 0x77, 0xdd,
0xa3, 0xcd, 0x99, 0x36, 0xe9, 0x3b, 0x4c, 0x67, 0x42, 0xd2, 0x27, 0x3e, 0xda, 0x08, 0x22, 0x23, 0xed, 0x0a, 0x30, 0xd9, 0xe6, 0x4c, 0xe9, 0xe4, 0x2d, 0x26, 0x33, 0x2e, 0xe8, 0x23, 0x97, 0x6d,
0xd8, 0xb1, 0xe4, 0xa5, 0xe2, 0x62, 0x2a, 0x90, 0x53, 0xe2, 0x58, 0x1a, 0x18, 0x39, 0x86, 0xbd, 0x00, 0x91, 0x08, 0x1e, 0x9a, 0xe3, 0x85, 0x4c, 0xf9, 0x94, 0x63, 0x4a, 0x89, 0x15, 0x69, 0x60,
0xc0, 0xee, 0x34, 0x5f, 0xb3, 0x9c, 0x1e, 0xb8, 0x28, 0xda, 0xb0, 0xd3, 0xa6, 0x52, 0x96, 0x57, 0xe4, 0x00, 0x76, 0xbc, 0xb8, 0xb5, 0xbc, 0x60, 0x39, 0x7d, 0x6c, 0xb3, 0x68, 0xc3, 0xd6, 0x9a,
0xb5, 0x79, 0x1a, 0xb4, 0x45, 0x98, 0xf5, 0xc9, 0x66, 0x26, 0x7d, 0xc7, 0x64, 0x86, 0x9a, 0x3e, 0x4c, 0x58, 0x5e, 0xd5, 0xe6, 0x89, 0xb7, 0x16, 0x60, 0x26, 0x26, 0xc3, 0x4c, 0xf2, 0x96, 0x89,
0xf3, 0x3e, 0x45, 0x90, 0xcd, 0x08, 0xcb, 0x73, 0xb5, 0x40, 0x2e, 0x0a, 0x4d, 0x0f, 0x7d, 0x7d, 0x0c, 0x15, 0x7d, 0xea, 0x62, 0x0a, 0x20, 0xc3, 0x08, 0xcb, 0x73, 0xb9, 0xc4, 0x94, 0x17, 0x8a,
0x6b, 0xc4, 0xf6, 0xa3, 0xd0, 0x4e, 0x27, 0xfd, 0x9f, 0x4b, 0x57, 0x45, 0x92, 0x4f, 0x61, 0x5f, 0xee, 0xb9, 0xfa, 0xd6, 0x88, 0xe9, 0x47, 0xae, 0xac, 0x4d, 0xfa, 0x91, 0xa5, 0xab, 0x3a, 0x92,
0x68, 0x21, 0x33, 0x6b, 0x28, 0x63, 0x06, 0x17, 0xec, 0x86, 0x3e, 0x77, 0x2c, 0xb7, 0x70, 0xeb, 0xcf, 0x60, 0x97, 0x2b, 0x2e, 0x32, 0xe3, 0x28, 0x63, 0x1a, 0x97, 0xec, 0x8a, 0x3e, 0xb3, 0x22,
0x87, 0xd0, 0x7c, 0xce, 0x72, 0x6d, 0x58, 0x3a, 0xa3, 0x1f, 0x39, 0xb6, 0x18, 0xb2, 0xb5, 0xe6, 0xd7, 0x70, 0x13, 0x07, 0x57, 0xe9, 0x9c, 0xe5, 0x4a, 0xb3, 0x64, 0x46, 0x3f, 0xb1, 0x62, 0x21,
0x52, 0xab, 0xe9, 0x94, 0x52, 0xf7, 0x18, 0x28, 0xd7, 0xd9, 0xd6, 0x5c, 0x69, 0xdd, 0xa5, 0xff, 0x64, 0x6a, 0x9d, 0x0a, 0x25, 0xa7, 0x53, 0x4a, 0xed, 0xa5, 0x3f, 0xd9, 0xce, 0x36, 0xee, 0x4a,
0xf7, 0xfe, 0xd5, 0xc8, 0xe8, 0xf7, 0x2e, 0xec, 0xbd, 0xb6, 0x99, 0xf9, 0xae, 0x1e, 0x49, 0x0a, 0x13, 0x2e, 0xfd, 0xd8, 0xc5, 0x57, 0x23, 0xd1, 0x9f, 0x5d, 0xd8, 0x39, 0x35, 0xcc, 0x7c, 0x5f,
0x5b, 0x7a, 0xee, 0xaa, 0xe6, 0x86, 0xad, 0x97, 0x54, 0x24, 0xf9, 0x04, 0x76, 0x25, 0x22, 0x2f, 0x8f, 0x24, 0x85, 0x2d, 0x35, 0xb7, 0x55, 0xb3, 0xc3, 0x36, 0x88, 0xab, 0x23, 0x79, 0x01, 0xdb,
0x10, 0xcb, 0x79, 0xc1, 0x99, 0xf1, 0xb3, 0xd7, 0x4b, 0x5a, 0xa8, 0x8d, 0xcd, 0x22, 0xbe, 0x2b, 0x02, 0x31, 0x2d, 0x10, 0xcb, 0x79, 0x91, 0x32, 0xed, 0x66, 0x6f, 0x10, 0xb7, 0x50, 0x93, 0x9b,
0x02, 0xe7, 0x9a, 0x8f, 0xad, 0x8d, 0x57, 0x5d, 0x7e, 0x89, 0x5a, 0xb3, 0x0c, 0xdd, 0xf0, 0x85, 0x41, 0x5c, 0x57, 0x78, 0xc9, 0x0d, 0x97, 0x5b, 0x1b, 0xaf, 0xba, 0xfc, 0x02, 0x95, 0x62, 0x19,
0x2e, 0x0f, 0x50, 0xb3, 0xcb, 0x37, 0xda, 0x5d, 0xfe, 0x31, 0x0c, 0xac, 0xce, 0x19, 0xde, 0x04, 0xda, 0xe1, 0xf3, 0x5d, 0xee, 0xa1, 0x66, 0x97, 0xf7, 0xda, 0x5d, 0xfe, 0x29, 0x8c, 0x8c, 0xcd,
0x43, 0x9b, 0x8e, 0xa3, 0x09, 0xda, 0x3c, 0x58, 0x80, 0x63, 0x8e, 0x06, 0xdd, 0x1c, 0xf6, 0x92, 0x19, 0x5e, 0x79, 0x47, 0x7d, 0x2b, 0xd1, 0x04, 0x0d, 0x0f, 0x06, 0x48, 0x31, 0x47, 0x8d, 0x76,
0x08, 0x19, 0xfd, 0xd9, 0x85, 0xc1, 0x4f, 0x88, 0xa5, 0x5e, 0x66, 0xe1, 0x18, 0xf6, 0x84, 0xc6, 0x0e, 0x07, 0x71, 0x80, 0x44, 0x7f, 0x77, 0x61, 0xf4, 0x33, 0x62, 0xa9, 0x56, 0x2c, 0x1c, 0xc0,
0x46, 0x79, 0x7c, 0x36, 0xda, 0x30, 0x19, 0x03, 0x69, 0x00, 0x3e, 0xd7, 0x7e, 0x2b, 0xad, 0x78, 0x0e, 0x57, 0xd8, 0x28, 0x8f, 0x63, 0xa3, 0x0d, 0x93, 0x23, 0x20, 0x0d, 0xc0, 0x71, 0xed, 0xb6,
0x79, 0xc4, 0x36, 0x79, 0xd8, 0x76, 0xeb, 0x7d, 0xe0, 0x76, 0x6b, 0x4f, 0xc2, 0xd6, 0x8a, 0x49, 0xd2, 0x9a, 0x9b, 0x7b, 0x6c, 0x93, 0xbb, 0x6d, 0xb7, 0xc1, 0x07, 0x6e, 0xb7, 0xf6, 0x24, 0x6c,
0xb8, 0x73, 0x2f, 0x8c, 0xfe, 0xee, 0xc0, 0xfe, 0xb7, 0xef, 0x4d, 0x33, 0x81, 0xff, 0xbd, 0x30, 0xad, 0x99, 0x84, 0x1b, 0xf7, 0x42, 0xf4, 0x6f, 0x07, 0x76, 0xbf, 0x7b, 0xa7, 0x9b, 0x04, 0xfe,
0x27, 0x30, 0x78, 0x5d, 0x22, 0x33, 0x68, 0xcf, 0x51, 0x82, 0x57, 0xe4, 0x05, 0xb8, 0xdb, 0xe9, 0xff, 0xd2, 0xfc, 0xa3, 0x0b, 0xfd, 0xd3, 0x9c, 0xa3, 0xdb, 0xeb, 0x45, 0xc9, 0x17, 0x4c, 0xa3,
0x1a, 0xa3, 0x7f, 0x06, 0x63, 0x77, 0x54, 0xdd, 0xa3, 0xbf, 0xa9, 0x2d, 0x01, 0xfd, 0x10, 0x81, 0xc9, 0xce, 0x7f, 0x1d, 0x6b, 0xa4, 0x99, 0x7c, 0xb7, 0x9d, 0x7c, 0x63, 0x4f, 0x6e, 0xb4, 0xf7,
0x5f, 0x5d, 0xc3, 0x7e, 0x80, 0x85, 0x58, 0xe0, 0x7e, 0x0b, 0xe7, 0xd0, 0x4f, 0x90, 0xf1, 0x5a, 0x64, 0x90, 0xfe, 0xe6, 0xfb, 0xd3, 0xef, 0xb5, 0xd2, 0x7f, 0x01, 0xdb, 0x0a, 0xcb, 0x05, 0x96,
0xff, 0xdd, 0x57, 0x3e, 0xba, 0xe4, 0xdd, 0xe6, 0x25, 0x3f, 0x89, 0x15, 0xdd, 0x6f, 0xf7, 0x67, 0x2d, 0x5a, 0x5b, 0xa8, 0xdd, 0xe1, 0x16, 0xb1, 0x34, 0xf9, 0x2f, 0x52, 0x8d, 0x98, 0xd8, 0xdc,
0x18, 0xbc, 0x71, 0xa3, 0xf6, 0x50, 0xcb, 0x76, 0x2f, 0x78, 0x53, 0x6f, 0xeb, 0x23, 0x1f, 0x43, 0xc9, 0xc4, 0xe6, 0x38, 0xae, 0x81, 0x68, 0x02, 0xa3, 0xd3, 0x12, 0x99, 0x46, 0xf3, 0x45, 0x8e,
0xa3, 0x97, 0x4d, 0x95, 0xfa, 0xdf, 0x17, 0x97, 0x8d, 0xfa, 0x1c, 0xab, 0xfe, 0x7c, 0x4c, 0xd4, 0xf1, 0x92, 0x3c, 0x07, 0xfb, 0x7c, 0xb0, 0x14, 0x0c, 0x4f, 0xe0, 0xc8, 0xbe, 0x2b, 0xec, 0xa5,
0xdf, 0xc3, 0xee, 0x39, 0x9a, 0xba, 0xd7, 0x1f, 0xa3, 0xeb, 0xcb, 0xd8, 0x29, 0x4d, 0x5e, 0xc2, 0x7b, 0x56, 0xb4, 0x14, 0xd4, 0x5d, 0x14, 0x7e, 0xb3, 0x33, 0xfb, 0x01, 0x1e, 0x42, 0x85, 0xdb,
0x86, 0x5d, 0xa1, 0x3a, 0xa4, 0xf0, 0xc0, 0xa7, 0xb0, 0x31, 0x53, 0x89, 0xe7, 0x18, 0xbd, 0x69, 0x3d, 0x9c, 0xc1, 0x30, 0x46, 0x96, 0xd6, 0xf6, 0x6f, 0x7e, 0xe8, 0x04, 0x8f, 0x99, 0x6e, 0xf3,
0x79, 0xa1, 0xc9, 0x19, 0xf4, 0xf0, 0xbd, 0x89, 0xe5, 0x0f, 0xbd, 0x7c, 0x7b, 0x2c, 0x93, 0x25, 0x31, 0x73, 0x18, 0x1a, 0xba, 0xdd, 0xef, 0x2f, 0x30, 0x7a, 0x6d, 0xb7, 0xcd, 0x5d, 0x3d, 0x9b,
0xdf, 0xe8, 0x33, 0x80, 0xe5, 0xea, 0xbf, 0xbf, 0xd3, 0x7e, 0x8c, 0xb8, 0x35, 0xf9, 0x7a, 0x79, 0xd5, 0xe8, 0x5c, 0xbd, 0xa9, 0xdf, 0x39, 0x21, 0x14, 0xbd, 0x6c, 0x9a, 0x54, 0xef, 0xdf, 0xdd,
0x67, 0xcb, 0xa0, 0x38, 0x08, 0x3e, 0xf3, 0x82, 0xad, 0x9b, 0x92, 0xb4, 0xb9, 0xcf, 0xfe, 0x58, 0x26, 0xeb, 0x33, 0xac, 0x46, 0xf4, 0x3e, 0x59, 0xff, 0x00, 0xdb, 0x67, 0xa8, 0xeb, 0x71, 0xbf,
0x83, 0xbe, 0xd5, 0xfe, 0x0b, 0x96, 0xd7, 0x22, 0x45, 0x72, 0x0a, 0x1b, 0xee, 0x87, 0x21, 0x21, 0x8f, 0xad, 0xaf, 0xc2, 0xa0, 0x14, 0x79, 0x09, 0x3d, 0xf3, 0x15, 0x51, 0x9e, 0xc2, 0xc7, 0x8e,
0x5e, 0x41, 0xfc, 0x5b, 0x74, 0x78, 0xd0, 0xc0, 0xc2, 0x7e, 0x79, 0x05, 0x50, 0x0f, 0x17, 0x09, 0xc2, 0xc6, 0x5a, 0x89, 0x9d, 0x44, 0xf4, 0xba, 0x15, 0x85, 0x22, 0x27, 0x30, 0xc0, 0x77, 0x3a,
0x2c, 0x8d, 0xf9, 0x1c, 0xae, 0x00, 0x35, 0x39, 0x85, 0x5e, 0xd5, 0xb8, 0xe4, 0x89, 0x67, 0x88, 0xd4, 0xdf, 0x73, 0xfa, 0xed, 0xcd, 0x14, 0xaf, 0xe4, 0xa2, 0xcf, 0x01, 0x56, 0x5f, 0xbf, 0xdb,
0x26, 0x62, 0x78, 0x0b, 0xd2, 0xd6, 0x52, 0x3d, 0x64, 0x95, 0xa5, 0xc6, 0x9c, 0x0e, 0x57, 0x80, 0x3b, 0xed, 0xa7, 0x40, 0x5a, 0x91, 0x6f, 0x56, 0x4f, 0x8d, 0xd2, 0x1b, 0xf6, 0x8a, 0x4f, 0x9d,
0x4e, 0xae, 0x6e, 0xd0, 0x4a, 0xae, 0x31, 0x05, 0xc3, 0x15, 0xa0, 0x2b, 0x66, 0xd5, 0x18, 0x95, 0x62, 0xeb, 0xb3, 0x1a, 0xb7, 0xa5, 0x4f, 0xfe, 0xda, 0x80, 0xa1, 0xb1, 0xfe, 0x2b, 0x96, 0x0b,
0x87, 0x51, 0xf7, 0x0e, 0x6f, 0x41, 0xfa, 0xb4, 0x43, 0xbe, 0x72, 0xcd, 0x54, 0x55, 0x9b, 0x3c, 0x9e, 0x20, 0x39, 0x86, 0x9e, 0x7d, 0x1b, 0x13, 0xe2, 0x0c, 0x84, 0xcf, 0xf1, 0xf1, 0xe3, 0x06,
0x5d, 0xf2, 0x44, 0xbd, 0x3a, 0x5c, 0x85, 0x5a, 0xe1, 0x13, 0xd8, 0x0a, 0x05, 0x23, 0xfb, 0xad, 0xe6, 0x57, 0xec, 0x2b, 0x80, 0x7a, 0xb8, 0x88, 0x17, 0x69, 0xcc, 0xe7, 0x78, 0x0d, 0xa8, 0xc8,
0xfa, 0x5d, 0x0d, 0xdb, 0x88, 0xfe, 0x66, 0xf2, 0xdb, 0x49, 0xa6, 0x54, 0x96, 0xe3, 0x38, 0x53, 0x31, 0x0c, 0xaa, 0xc6, 0x25, 0x8f, 0x9c, 0x40, 0x30, 0x11, 0xe3, 0x6b, 0x90, 0x32, 0x9e, 0xea,
0x39, 0x93, 0xd9, 0x58, 0x95, 0xd9, 0xc4, 0xfd, 0x97, 0xb8, 0x98, 0x4f, 0x27, 0xe6, 0xa6, 0x40, 0x21, 0xab, 0x3c, 0x35, 0xe6, 0x74, 0xbc, 0x06, 0xb4, 0x7a, 0x75, 0x83, 0x56, 0x7a, 0x8d, 0x29,
0x3d, 0x99, 0x49, 0xb5, 0x90, 0xee, 0x5f, 0x46, 0x71, 0x71, 0xb1, 0xe9, 0x1e, 0xbf, 0xf8, 0x27, 0x18, 0xaf, 0x01, 0x6d, 0x31, 0xab, 0xc6, 0xa8, 0x22, 0x0c, 0xba, 0x77, 0x7c, 0x0d, 0x52, 0xc7,
0x00, 0x00, 0xff, 0xff, 0x4a, 0xa4, 0x7a, 0x56, 0x7b, 0x0c, 0x00, 0x00, 0x1d, 0xf2, 0xb5, 0x6d, 0xa6, 0xaa, 0xda, 0xe4, 0xc9, 0x4a, 0x26, 0xe8, 0xd5, 0xf1, 0x3a, 0xd4,
0x28, 0x1f, 0xc2, 0x96, 0x2f, 0x18, 0xd9, 0x6d, 0xd5, 0xef, 0x72, 0xdc, 0x46, 0xd4, 0xb7, 0x93,
0xdf, 0x0f, 0x33, 0x29, 0xb3, 0x1c, 0x8f, 0x32, 0x99, 0x33, 0x91, 0x1d, 0xc9, 0x32, 0x9b, 0xd8,
0xbf, 0x53, 0xe7, 0xf3, 0xe9, 0x44, 0x5f, 0x15, 0xa8, 0x26, 0x33, 0x21, 0x97, 0xc2, 0xfe, 0xd1,
0x2a, 0xce, 0xcf, 0xfb, 0xf6, 0xf2, 0xcb, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x11, 0xa6, 0x77,
0x7c, 0x7e, 0x0d, 0x00, 0x00,
} }

View File

@@ -84,6 +84,17 @@ message ExtPeersResponse {
int32 keepalive = 13; int32 keepalive = 13;
} }
message Client {
string privatekey = 1;
string publickey = 2;
string accesskey = 3;
string address = 4;
string address6 = 5;
string serverendpoint = 6;
string serverport = 7;
string serverkey = 8;
}
message CreateNodeReq { message CreateNodeReq {
Node node = 1; // Node id blank Node node = 1; // Node id blank
} }

12
main.go
View File

@@ -59,6 +59,16 @@ func main() {
installserver = true installserver = true
} }
if servercfg.IsGRPCWireGuard() {
err = serverctl.InitServerWireGuard()
if err != nil {
log.Fatal(err)
}
err = serverctl.ReconfigureServerWireGuard()
if err != nil {
log.Fatal(err)
}
}
//NOTE: Removed Check and Logic for DNS Mode //NOTE: Removed Check and Logic for DNS Mode
//Reasoning. DNS Logic is very small on server. Can run with little/no impact. Just sets a tiny config file. //Reasoning. DNS Logic is very small on server. Can run with little/no impact. Just sets a tiny config file.
//Real work is done by CoreDNS //Real work is done by CoreDNS
@@ -113,7 +123,7 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
listener, err := net.Listen("tcp", ":"+grpcport) listener, err := net.Listen("tcp", ":"+grpcport)
// Handle errors if any // Handle errors if any
if err != nil { if err != nil {
log.Fatalf("Unable to listen on port" + grpcport + ": %v", err) log.Fatalf("Unable to listen on port " + grpcport + ", error: %v", err)
} }
s := grpc.NewServer( s := grpc.NewServer(

BIN
models/.serverclient.go.swp Normal file

Binary file not shown.

View File

@@ -31,6 +31,9 @@ type Network struct {
AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"` AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"`
IsLocal *bool `json:"islocal" bson:"islocal"` IsLocal *bool `json:"islocal" bson:"islocal"`
IsDualStack *bool `json:"isdualstack" bson:"isdualstack"` IsDualStack *bool `json:"isdualstack" bson:"isdualstack"`
IsIPv4 string `json:"isipv4" bson:"isipv4"`
IsIPv6 string `json:"isipv6" bson:"isipv6"`
IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub"`
LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"` LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
//can't have min=1 with omitempty //can't have min=1 with omitempty
DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"` DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
@@ -103,4 +106,11 @@ func (network *Network) SetDefaults() {
signup := false signup := false
network.AllowManualSignUp = &signup network.AllowManualSignUp = &signup
} }
if (network.IsDualStack != nil) && *network.IsDualStack {
network.IsIPv6 = "yes"
network.IsIPv4 = "yes"
} else if network.IsGRPCHub != "yes" {
network.IsIPv6 = "no"
network.IsIPv4 = "yes"
}
} }

16
models/serverclient.go Normal file
View File

@@ -0,0 +1,16 @@
package models
import (
)
type ServerClient struct {
PrivateKey string `json:"privatekey" bson:"privatekey"`
PublicKey string `json:"publickey" bson:"publickey"`
AccessKey string `json:"publickey" bson:"accesskey"`
Address string `json:"address" bson:"address"`
Address6 string `json:"address6" bson:"address6"`
Network string `json:"network" bson:"network"`
ServerEndpoint string `json:"serverendpoint" bson:"serverendpoint"`
ServerPort string `json:"serverport" bson:"serverport"`
ServerKey string `json:"serverkey" bson:"serverkey"`
IsServer string `json:"isserver" bson:"isserver"`
}

17
models/wglink.go Normal file
View File

@@ -0,0 +1,17 @@
package models
import (
"github.com/vishvananda/netlink"
)
type WireGuardLink struct {
LinkAttrs *netlink.LinkAttrs
}
func (link *WireGuardLink) Type() string {
return "wireguard"
}
func (link *WireGuardLink) Attrs() *netlink.LinkAttrs {
return link.LinkAttrs
}

View File

@@ -1,4 +1,4 @@
package functions package auth
import ( import (
"github.com/gravitl/netmaker/netclient/config" "github.com/gravitl/netmaker/netclient/config"
@@ -19,7 +19,6 @@ func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, e
home := "/etc/netclient" home := "/etc/netclient"
tokentext, err := ioutil.ReadFile(home + "/nettoken-"+network) tokentext, err := ioutil.ReadFile(home + "/nettoken-"+network)
if err != nil { if err != nil {
fmt.Println("Error reading token. Logging in to retrieve new token.")
err = AutoLogin(client, network) err = AutoLogin(client, network)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong with Auto Login: %v", err)) return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong with Auto Login: %v", err))

View File

@@ -0,0 +1,100 @@
package command
import (
"github.com/gravitl/netmaker/netclient/functions"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
"golang.zx2c4.com/wireguard/wgctrl"
nodepb "github.com/gravitl/netmaker/grpc"
"os"
"strings"
"log"
)
var (
wgclient *wgctrl.Client
)
var (
wcclient nodepb.NodeServiceClient
)
func Register(cfg config.ClientConfig) error {
err := functions.Register(cfg)
return err
}
func Join(cfg config.ClientConfig) error {
err := functions.JoinNetwork(cfg)
if err != nil {
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
log.Println("Error installing: ", err)
err = functions.LeaveNetwork(cfg.Network)
if err != nil {
err = local.WipeLocal(cfg.Network)
if err != nil {
log.Println("Error removing artifacts: ", err)
}
err = local.RemoveSystemDServices(cfg.Network)
if err != nil {
log.Println("Error removing services: ", err)
}
}
os.Exit(1)
} else {
log.Println(err.Error())
os.Exit(1)
}
}
log.Println("joined " + cfg.Network)
if cfg.Daemon != "off" {
err = functions.Install(cfg)
log.Println("installed daemon")
}
return err
}
func CheckIn(cfg config.ClientConfig) error {
if cfg.Network == "nonetwork" || cfg.Network == "" {
log.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
log.Println("Beginning node check in for network " + cfg.Network)
err := functions.CheckIn(cfg.Network)
if err != nil {
log.Println("Error checking in: ", err)
os.Exit(1)
}
return nil
}
func Leave(cfg config.ClientConfig) error {
err := functions.LeaveNetwork(cfg.Network)
if err != nil {
log.Println("Error attempting to leave network " + cfg.Network)
}
return err
}
func Push(cfg config.ClientConfig) error {
log.Println("pushing to network")
return nil
}
func Pull(cfg config.ClientConfig) error {
log.Println("pulling from network")
return nil
}
func Status(cfg config.ClientConfig) error {
log.Println("retrieving network status")
return nil
}
func Uninstall(cfg config.ClientConfig) error {
log.Println("uninstalling")
return nil
}

View File

@@ -1,22 +1,24 @@
package config package config
import ( import (
// "github.com/davecgh/go-spew/spew" //"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
"os" "os"
"encoding/base64"
"errors" "errors"
"strings"
"fmt" "fmt"
"log" "log"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
//homedir "github.com/mitchellh/go-homedir" nodepb "github.com/gravitl/netmaker/grpc"
) )
//var Config *ClientConfig
// Configurations exported
type ClientConfig struct { type ClientConfig struct {
Server ServerConfig `yaml:"server"` Server ServerConfig `yaml:"server"`
Node NodeConfig `yaml:"node"` Node NodeConfig `yaml:"node"`
Network string Network string `yaml:"network"`
Daemon string `yaml:"daemon"`
OperatingSystem string `yaml:"operatingsystem"`
} }
type ServerConfig struct { type ServerConfig struct {
Address string `yaml:"address"` Address string `yaml:"address"`
@@ -32,11 +34,11 @@ type NodeConfig struct {
LocalAddress string `yaml:"localaddress"` LocalAddress string `yaml:"localaddress"`
WGAddress string `yaml:"wgaddress"` WGAddress string `yaml:"wgaddress"`
WGAddress6 string `yaml:"wgaddress6"` WGAddress6 string `yaml:"wgaddress6"`
RoamingOff bool `yaml:"roamingoff"` Roaming string `yaml:"roaming"`
DNSOff bool `yaml:"dnsoff"` DNS string `yaml:"dns"`
IsLocal bool `yaml:"islocal"` IsLocal string `yaml:"islocal"`
IsDualStack bool `yaml:"isdualstack"` IsDualStack string `yaml:"isdualstack"`
IsIngressGateway bool `yaml:"isingressgateway"` IsIngressGateway string `yaml:"isingressgateway"`
AllowedIPs string `yaml:"allowedips"` AllowedIPs string `yaml:"allowedips"`
LocalRange string `yaml:"localrange"` LocalRange string `yaml:"localrange"`
PostUp string `yaml:"postup"` PostUp string `yaml:"postup"`
@@ -56,8 +58,6 @@ func Write(config *ClientConfig, network string) error{
err := errors.New("No network provided. Exiting.") err := errors.New("No network provided. Exiting.")
return err return err
} }
nofile := false
//home, err := homedir.Dir()
_, err := os.Stat("/etc/netclient") _, err := os.Stat("/etc/netclient")
if os.IsNotExist(err) { if os.IsNotExist(err) {
os.Mkdir("/etc/netclient", 744) os.Mkdir("/etc/netclient", 744)
@@ -71,29 +71,12 @@ func Write(config *ClientConfig, network string) error{
} }
file := fmt.Sprintf(home + "/netconfig-" + network) file := fmt.Sprintf(home + "/netconfig-" + network)
f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
if err != nil {
nofile = true
//fmt.Println("Could not access " + home + "/netconfig, proceeding...")
}
defer f.Close() defer f.Close()
if !nofile {
err = yaml.NewEncoder(f).Encode(config) err = yaml.NewEncoder(f).Encode(config)
if err != nil { if err != nil {
fmt.Println("trouble writing file")
return err return err
} }
} else {
newf, err := os.Create(home + "/netconfig-" + network)
err = yaml.NewEncoder(newf).Encode(config)
defer newf.Close()
if err != nil {
return err
}
}
return err return err
} }
func WriteServer(server string, accesskey string, network string) error{ func WriteServer(server string, accesskey string, network string) error{
@@ -212,16 +195,158 @@ func(config *ClientConfig) ReadConfig() {
} }
} }
func ModConfig(node *nodepb.Node) error{
network := node.Nodenetwork
if network == "" {
return errors.New("No Network Provided")
}
var modconfig ClientConfig
var err error
if FileExists("/etc/netclient/netconfig-"+network) {
useconfig, err := ReadConfig(network)
if err != nil {
return err
}
modconfig = *useconfig
}
nodecfg := modconfig.Node
if node.Name != ""{
nodecfg.Name = node.Name
}
if node.Interface != ""{
nodecfg.Interface = node.Interface
}
if node.Nodenetwork != ""{
nodecfg.Network = node.Nodenetwork
}
if node.Macaddress != ""{
nodecfg.MacAddress = node.Macaddress
}
if node.Localaddress != ""{
nodecfg.LocalAddress = node.Localaddress
}
if node.Postup != ""{
nodecfg.PostUp = node.Postup
}
if node.Postdown != ""{
nodecfg.PostDown = node.Postdown
}
if node.Listenport != 0{
nodecfg.Port = node.Listenport
}
if node.Keepalive != 0{
nodecfg.KeepAlive = node.Keepalive
}
if node.Publickey != ""{
nodecfg.PublicKey = node.Publickey
}
if node.Endpoint != ""{
nodecfg.Endpoint = node.Endpoint
}
if node.Password != ""{
nodecfg.Password = node.Password
}
if node.Address != ""{
nodecfg.WGAddress = node.Address
}
if node.Address6 != ""{
nodecfg.WGAddress6 = node.Address6
}
if node.Postchanges != "" {
nodecfg.PostChanges = node.Postchanges
}
if node.Dnsoff == true {
nodecfg.DNS = "off"
}
if node.Isdualstack == true {
nodecfg.IsDualStack = "yes"
}
if node.Isingressgateway {
nodecfg.IsIngressGateway = "yes"
} else {
nodecfg.IsIngressGateway = "no"
}
if node.Localrange != "" && node.Islocal {
nodecfg.IsLocal = "yes"
nodecfg.LocalRange = node.Localrange
}
modconfig.Node = nodecfg
err = Write(&modconfig, network)
return err
}
func GetCLIConfig(c *cli.Context) (ClientConfig, error){
var cfg ClientConfig
if c.String("token") != "" {
tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))
if err != nil {
log.Println("error decoding token")
return cfg, err
}
token := string(tokenbytes)
tokenvals := strings.Split(token, "|")
cfg.Server.Address = tokenvals[0]
cfg.Network = tokenvals[1]
cfg.Node.Network = tokenvals[1]
cfg.Server.AccessKey = tokenvals[2]
cfg.Node.LocalRange = tokenvals[3]
if c.String("server") != "" {
cfg.Server.Address = c.String("server")
}
if c.String("key") != "" {
cfg.Server.AccessKey = c.String("key")
}
if c.String("network") != "all" {
cfg.Network = c.String("network")
cfg.Node.Network = c.String("network")
}
if c.String("localrange") != "" {
cfg.Node.LocalRange = c.String("localrange")
}
} else {
cfg.Server.Address = c.String("server")
cfg.Server.AccessKey = c.String("key")
cfg.Network = c.String("network")
cfg.Node.Network = c.String("network")
cfg.Node.LocalRange = c.String("localrange")
}
cfg.Node.Name = c.String("name")
cfg.Node.Interface = c.String("interface")
cfg.Node.Password = c.String("password")
cfg.Node.MacAddress = c.String("macaddress")
cfg.Node.LocalAddress = c.String("localaddress")
cfg.Node.LocalRange = c.String("localrange")
cfg.Node.WGAddress = c.String("address")
cfg.Node.WGAddress6 = c.String("addressIPV6")
cfg.Node.Roaming = c.String("")
cfg.Node.DNS = c.String("")
cfg.Node.IsLocal = c.String("")
cfg.Node.IsDualStack = c.String("")
cfg.Node.IsIngressGateway = c.String("")
cfg.Node.PostUp = c.String("")
cfg.Node.PostDown = c.String("")
cfg.Node.Port = int32(c.Int(""))
cfg.Node.KeepAlive = int32(c.Int(""))
cfg.Node.PublicKey = c.String("")
cfg.Node.PrivateKey = c.String("")
cfg.Node.Endpoint = c.String("")
cfg.Node.IPForwarding = c.String("")
return cfg, nil
}
func ReadConfig(network string) (*ClientConfig, error) { func ReadConfig(network string) (*ClientConfig, error) {
if network == "" { if network == "" {
err := errors.New("No network provided. Exiting.") err := errors.New("No network provided. Exiting.")
return nil, err return nil, err
} }
nofile := false nofile := false
//home, err := homedir.Dir()
home := "/etc/netclient" home := "/etc/netclient"
file := fmt.Sprintf(home + "/netconfig-" + network) file := fmt.Sprintf(home + "/netconfig-" + network)
f, err := os.Open(file) f, err := os.Open(file)
if err != nil { if err != nil {
nofile = true nofile = true
} }
@@ -239,3 +364,12 @@ func ReadConfig(network string) (*ClientConfig, error) {
} }
return &cfg, err return &cfg, err
} }
func FileExists(f string) bool {
info, err := os.Stat(f)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}

Binary file not shown.

View File

@@ -0,0 +1,286 @@
package functions
import (
"fmt"
"context"
"strings"
"log"
"net"
"os/exec"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/wireguard"
"github.com/gravitl/netmaker/netclient/server"
"github.com/gravitl/netmaker/netclient/auth"
nodepb "github.com/gravitl/netmaker/grpc"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
//homedir "github.com/mitchellh/go-homedir"
)
func CheckIn(network string) error {
node := server.GetNode(network)
cfg, err := config.ReadConfig(network)
if err != nil {
return err
}
nodecfg := cfg.Node
servercfg := cfg.Server
fmt.Println("Checking into server: " + servercfg.Address)
setupcheck := true
ipchange := false
if !(nodecfg.IPForwarding == "off") {
out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
if err != nil {
fmt.Println(err)
fmt.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
} else {
s := strings.Fields(string(out))
if s[2] != "1" {
_, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
if err != nil {
fmt.Println(err)
fmt.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
}
}
}
}
if nodecfg.Roaming != "off" {
if nodecfg.IsLocal != "yes" {
fmt.Println("Checking to see if public addresses have changed")
extIP, err := getPublicIP()
if err != nil {
fmt.Printf("Error encountered checking ip addresses: %v", err)
}
if nodecfg.Endpoint != extIP && extIP != "" {
fmt.Println("Endpoint has changed from " +
nodecfg.Endpoint + " to " + extIP)
fmt.Println("Updating address")
nodecfg.Endpoint = extIP
nodecfg.PostChanges = "true"
node.Endpoint = extIP
node.Postchanges = "true"
ipchange = true
}
intIP, err := getPrivateAddr()
if err != nil {
fmt.Printf("Error encountered checking ip addresses: %v", err)
}
if nodecfg.LocalAddress != intIP && intIP != "" {
fmt.Println("Local Address has changed from " +
nodecfg.LocalAddress + " to " + intIP)
fmt.Println("Updating address")
nodecfg.LocalAddress = intIP
nodecfg.PostChanges = "true"
node.Localaddress = intIP
node.Postchanges = "true"
ipchange = true
}
} else {
fmt.Println("Checking to see if local addresses have changed")
localIP, err := getLocalIP(nodecfg.LocalRange)
if err != nil {
fmt.Printf("Error encountered checking ip addresses: %v", err)
}
if nodecfg.Endpoint != localIP && localIP != "" {
fmt.Println("Endpoint has changed from " +
nodecfg.Endpoint + " to " + localIP)
fmt.Println("Updating address")
nodecfg.Endpoint = localIP
nodecfg.LocalAddress = localIP
nodecfg.PostChanges = "true"
node.Endpoint = localIP
node.Localaddress = localIP
node.Postchanges = "true"
ipchange = true
}
}
if node.Postchanges != "true" {
fmt.Println("Addresses have not changed.")
}
}
if ipchange {
err := config.ModConfig(&node)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
err = wireguard.SetWGConfig(network)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
node = server.GetNode(network)
cfg, err := config.ReadConfig(network)
if err != nil {
return err
}
nodecfg = cfg.Node
}
var wcclient nodepb.NodeServiceClient
var requestOpts grpc.DialOption
requestOpts = grpc.WithInsecure()
conn, err := grpc.Dial(servercfg.Address, requestOpts)
if err != nil {
fmt.Printf("Cant dial GRPC server: %v", err)
return err
}
wcclient = nodepb.NewNodeServiceClient(conn)
ctx := context.Background()
fmt.Println("Authenticating with GRPC Server")
ctx, err = auth.SetJWT(wcclient, network)
if err != nil {
fmt.Printf("Failed to authenticate: %v", err)
return err
}
fmt.Println("Authenticated")
fmt.Println("Checking In.")
var header metadata.MD
node.Nodenetwork = network
checkinres, err := wcclient.CheckIn(
ctx,
&nodepb.CheckInReq{
Node: &node,
},
grpc.Header(&header),
)
if err != nil {
if checkinres != nil && checkinres.Checkinresponse.Ispending {
fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
return nil
}
fmt.Printf("Unable to process Check In request: %v", err)
return err
}
fmt.Println("Checked in.")
if checkinres.Checkinresponse.Ispending {
fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
return err
}
newinterface := server.GetNode(network).Interface
readreq := &nodepb.ReadNodeReq{
Macaddress: node.Macaddress,
Network: node.Nodenetwork,
}
readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
if err != nil {
fmt.Printf("Error: %v", err)
} else {
currentiface := readres.Node.Interface
ifaceupdate := newinterface != currentiface
if err != nil {
log.Printf("Error retrieving interface: %v", err)
}
if ifaceupdate {
fmt.Println("Interface update: " + currentiface +
" >>>> " + newinterface)
err := DeleteInterface(currentiface, nodecfg.PostDown)
if err != nil {
fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
}
err = wireguard.SetWGConfig(network)
if err != nil {
log.Printf("Error updating interface: %v", err)
}
}
}
if checkinres.Checkinresponse.Needconfigupdate {
fmt.Println("Server has requested that node update config.")
fmt.Println("Updating config from remote server.")
req := &nodepb.ReadNodeReq{
Macaddress: node.Macaddress,
Network: node.Nodenetwork,
}
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
err = config.ModConfig(readres.Node)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
err = wireguard.SetWGConfig(network)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
setupcheck = false
} else if nodecfg.PostChanges == "true" {
fmt.Println("Node has requested to update remote config.")
fmt.Println("Posting local config to remote server.")
postnode := server.GetNode(network)
req := &nodepb.UpdateNodeReq{
Node: &postnode,
}
res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
res.Node.Postchanges = "false"
err = config.ModConfig(res.Node)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
err = wireguard.SetWGConfig(network)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
setupcheck = false
}
if checkinres.Checkinresponse.Needkeyupdate {
fmt.Println("Server has requested that node update key pairs.")
fmt.Println("Proceeding to re-generate key pairs for Wiregard.")
err = wireguard.SetWGKeyConfig(network, servercfg.Address)
if err != nil {
return err
log.Fatalf("Unable to process reset keys request: %v", err)
}
setupcheck = false
}
if checkinres.Checkinresponse.Needpeerupdate {
fmt.Println("Server has requested that node update peer list.")
fmt.Println("Updating peer list from remote server.")
err = wireguard.SetWGConfig(network)
if err != nil {
return err
log.Fatalf("Unable to process Set Peers request: %v", err)
}
setupcheck = false
}
if checkinres.Checkinresponse.Needdelete {
fmt.Println("This machine got the delete signal. Deleting.")
err := LeaveNetwork(network)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
}
if setupcheck {
iface := nodecfg.Interface
_, err := net.InterfaceByName(iface)
if err != nil {
fmt.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
err = wireguard.SetWGKeyConfig(network, servercfg.Address)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
}
}
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
package functions
import (
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
)
func Install(cfg config.ClientConfig) error {
var err error
err = local.ConfigureSystemD(cfg.Network)
return err
}
func getOS() (config.ClientConfig, error) {
var cfg config.ClientConfig
return cfg, nil
}

237
netclient/functions/join.go Normal file
View File

@@ -0,0 +1,237 @@
package functions
import (
"fmt"
"errors"
"context"
"log"
"net"
"strconv"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/wireguard"
"github.com/gravitl/netmaker/netclient/server"
"github.com/gravitl/netmaker/netclient/local"
nodepb "github.com/gravitl/netmaker/grpc"
"golang.zx2c4.com/wireguard/wgctrl"
"google.golang.org/grpc"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
//homedir "github.com/mitchellh/go-homedir"
)
func JoinNetwork(cfg config.ClientConfig) error {
hasnet := local.HasNetwork(cfg.Network)
if hasnet {
err := errors.New("ALREADY_INSTALLED. Netclient appears to already be installed for cfg.Network " + cfg.Network + ". To re-install, please remove by executing 'sudo netclient -c remove -n " + cfg.Network + "'. Then re-run the install command.")
return err
}
err := config.Write(&cfg, cfg.Network)
if err != nil {
return err
}
wgclient, err := wgctrl.New()
if err != nil {
return err
}
defer wgclient.Close()
if cfg.Node.LocalRange != "" {
if cfg.Node.LocalAddress == "" {
ifaces, err := net.Interfaces()
if err != nil {
return err
}
_, localrange, err := net.ParseCIDR(cfg.Node.LocalRange)
if err != nil {
return err
}
var local string
found := false
for _, i := range ifaces {
if i.Flags&net.FlagUp == 0 {
continue // interface down
}
if i.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := i.Addrs()
if err != nil {
return err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
if !found {
ip = v.IP
local = ip.String()
if cfg.Node.IsLocal == "yes" {
found = localrange.Contains(ip)
} else {
found = true
}
}
case *net.IPAddr:
if !found {
ip = v.IP
local = ip.String()
if cfg.Node.IsLocal == "yes" {
found = localrange.Contains(ip)
} else {
found = true
}
}
}
}
}
cfg.Node.LocalAddress = local
}
}
if cfg.Node.Endpoint == "" {
if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
cfg.Node.Endpoint = cfg.Node.LocalAddress
} else {
cfg.Node.Endpoint, err = getPublicIP()
if err != nil {
fmt.Println("Error setting cfg.Node.Endpoint.")
return err
}
}
} else {
cfg.Node.Endpoint = cfg.Node.Endpoint
fmt.Println("Endpoint set in config. Setting to address: " + cfg.Node.Endpoint)
}
if cfg.Node.PrivateKey == "" {
privatekey, err := wgtypes.GeneratePrivateKey()
if err != nil {
log.Fatal(err)
}
cfg.Node.PrivateKey = privatekey.String()
cfg.Node.PublicKey = privatekey.PublicKey().String()
}
if cfg.Node.MacAddress == "" {
macs, err := getMacAddr()
if err != nil {
return err
} else if len(macs) == 0 {
log.Fatal()
} else {
cfg.Node.MacAddress = macs[0]
}
}
var wcclient nodepb.NodeServiceClient
var requestOpts grpc.DialOption
requestOpts = grpc.WithInsecure()
conn, err := grpc.Dial(cfg.Server.Address, requestOpts)
if err != nil {
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
}
wcclient = nodepb.NewNodeServiceClient(conn)
postnode := &nodepb.Node{
Password: cfg.Node.Password,
Macaddress: cfg.Node.MacAddress,
Accesskey: cfg.Server.AccessKey,
Nodenetwork: cfg.Network,
Listenport: cfg.Node.Port,
Postup: cfg.Node.PostUp,
Postdown: cfg.Node.PostDown,
Keepalive: cfg.Node.KeepAlive,
Localaddress: cfg.Node.LocalAddress,
Interface: cfg.Node.Interface,
Publickey: cfg.Node.PublicKey,
Name: cfg.Node.Name,
Endpoint: cfg.Node.Endpoint,
}
err = config.ModConfig(postnode)
if err != nil {
return err
}
res, err := wcclient.CreateNode(
context.TODO(),
&nodepb.CreateNodeReq{
Node: postnode,
},
)
if err != nil {
return err
}
node := res.Node
if err != nil {
return err
}
fmt.Println("Node Settings: ")
fmt.Println(" Password: " + node.Password)
fmt.Println(" WG Address: " + node.Address)
fmt.Println(" WG ipv6 Address: " + node.Address6)
fmt.Println(" Network: " + node.Nodenetwork)
fmt.Println(" Public Endpoint: " + node.Endpoint)
fmt.Println(" Local Address: " + node.Localaddress)
fmt.Println(" Name: " + node.Name)
fmt.Println(" Interface: " + node.Interface)
fmt.Println(" PostUp: " + node.Postup)
fmt.Println(" PostDown: " + node.Postdown)
fmt.Println(" Port: " + strconv.FormatInt(int64(node.Listenport), 10))
fmt.Println(" KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
fmt.Println(" Public Key: " + node.Publickey)
fmt.Println(" Mac Address: " + node.Macaddress)
fmt.Println(" Is Local?: " + strconv.FormatBool(node.Islocal))
fmt.Println(" Is Dual Stack?: " + strconv.FormatBool(node.Isdualstack))
fmt.Println(" Is Ingress Gateway?: " + strconv.FormatBool(node.Isingressgateway))
fmt.Println(" Local Range: " + node.Localrange)
if node.Dnsoff==true {
cfg.Node.DNS = "yes"
}
if !(cfg.Node.IsLocal == "yes") && node.Islocal && node.Localrange != "" {
node.Localaddress, err = getLocalIP(node.Localrange)
if err != nil {
return err
}
node.Endpoint = node.Localaddress
}
err = config.ModConfig(node)
if err != nil {
return err
}
if node.Ispending {
fmt.Println("Node is marked as PENDING.")
fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
if cfg.Daemon != "no" {
fmt.Println("Configuring Netmaker Service.")
err = local.ConfigureSystemD(cfg.Network)
return err
}
}
peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, cfg.Network, cfg.Server.Address, node.Isdualstack, node.Isingressgateway)
if err != nil {
return err
}
err = wireguard.StorePrivKey(cfg.Node.PrivateKey, cfg.Network)
if err != nil {
return err
}
err = wireguard.InitWireguard(node, cfg.Node.PrivateKey, peers, hasGateway, gateways)
if err != nil {
return err
}
if cfg.Daemon == "off" {
err = local.ConfigureSystemD(cfg.Network)
}
if err != nil {
return err
}
return err
}

View File

@@ -0,0 +1,114 @@
package functions
import (
"fmt"
"errors"
"context"
"log"
"net"
"strconv"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/wireguard"
"github.com/gravitl/netmaker/netclient/server"
"github.com/gravitl/netmaker/netclient/local"
nodepb "github.com/gravitl/netmaker/grpc"
"golang.zx2c4.com/wireguard/wgctrl"
"google.golang.org/grpc"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
//homedir "github.com/mitchellh/go-homedir"
)
func Register(cfg config.ClientConfig) error {
if err != nil {
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
}
wcclient = nodepb.NewNodeServiceClient(conn)
postclient := &models.ServerClient{
AccessKey: cfg.Server.AccessKey,
Publickey: cfg.Node.PublicKey,
Privatekey: cfg.Node.PublicKey,
Address: cfg.Node.Address,
Address6: cfg.Node.Address6,
Network: "comms"
}
bytes, err := json.Marshal(postclient)
body := bytes.NewBuffer(bytes)
res, err := http.Post("http://"+cfg.Server.Address+""jsonplaceholder.typicode.com/posts/1")
if err != nil {
return err
}
node := res.Node
if err != nil {
return err
}
fmt.Println("Node Settings: ")
fmt.Println(" Password: " + node.Password)
fmt.Println(" WG Address: " + node.Address)
fmt.Println(" WG ipv6 Address: " + node.Address6)
fmt.Println(" Network: " + node.Nodenetwork)
fmt.Println(" Public Endpoint: " + node.Endpoint)
fmt.Println(" Local Address: " + node.Localaddress)
fmt.Println(" Name: " + node.Name)
fmt.Println(" Interface: " + node.Interface)
fmt.Println(" PostUp: " + node.Postup)
fmt.Println(" PostDown: " + node.Postdown)
fmt.Println(" Port: " + strconv.FormatInt(int64(node.Listenport), 10))
fmt.Println(" KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
fmt.Println(" Public Key: " + node.Publickey)
fmt.Println(" Mac Address: " + node.Macaddress)
fmt.Println(" Is Local?: " + strconv.FormatBool(node.Islocal))
fmt.Println(" Is Dual Stack?: " + strconv.FormatBool(node.Isdualstack))
fmt.Println(" Is Ingress Gateway?: " + strconv.FormatBool(node.Isingressgateway))
fmt.Println(" Local Range: " + node.Localrange)
if node.Dnsoff==true {
cfg.Node.DNS = "yes"
}
if !(cfg.Node.IsLocal == "yes") && node.Islocal && node.Localrange != "" {
node.Localaddress, err = getLocalIP(node.Localrange)
if err != nil {
return err
}
node.Endpoint = node.Localaddress
}
err = config.ModConfig(node)
if err != nil {
return err
}
if node.Ispending {
fmt.Println("Node is marked as PENDING.")
fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
if cfg.Daemon != "no" {
fmt.Println("Configuring Netmaker Service.")
err = local.ConfigureSystemD(cfg.Network)
return err
}
}
peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, cfg.Network, cfg.Server.Address, node.Isdualstack, node.Isingressgateway)
if err != nil {
return err
}
err = wireguard.StorePrivKey(cfg.Node.PrivateKey, cfg.Network)
if err != nil {
return err
}
err = wireguard.InitWireguard(node, cfg.Node.PrivateKey, peers, hasGateway, gateways)
if err != nil {
return err
}
if cfg.Daemon == "off" {
err = local.ConfigureSystemD(cfg.Network)
}
if err != nil {
return err
}
return err
}

View File

@@ -1,7 +1,8 @@
package functions package local
import ( import (
//"github.com/davecgh/go-spew/spew" //"github.com/davecgh/go-spew/spew"
"github.com/gravitl/netmaker/netclient/config"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
@@ -12,6 +13,19 @@ import (
"os/exec" "os/exec"
) )
func RunCmds(commands []string) error {
var err error
for _, command := range commands {
fmt.Println("Running command: " + command)
args := strings.Fields(command)
out, err := exec.Command(args[0], args[1:]...).Output()
fmt.Println(string(out))
if err != nil {
return err
}
}
return err
}
func FileExists(f string) bool { func FileExists(f string) bool {
info, err := os.Stat(f) info, err := os.Stat(f)
@@ -92,7 +106,7 @@ Wants=netclient.timer
[Service] [Service]
Type=simple Type=simple
ExecStart=/etc/netclient/netclient -c checkin -n %i ExecStart=/etc/netclient/netclient checkin -n %i
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@@ -213,38 +227,11 @@ func RemoveSystemDServices(network string) error {
fmt.Println(err) fmt.Println(err)
} }
cmdSysDisableService := exec.Command("systemctl","disable","netclient@.service")/* &exec.Cmd { cmdSysDisableService := exec.Command("systemctl","disable","netclient@.service")
Path: sysExec, cmdSysDaemonReload := exec.Command("systemctl","daemon-reload")
Args: []string{ sysExec, "disable", "netclient@.service"}, cmdSysResetFailed := exec.Command("systemctl","reset-failed")
Stdout: os.Stdout, cmdSysStopTimer := exec.Command("systemctl", "stop", "netclient-"+network+".timer")
Stderr: os.Stdout, cmdSysDisableTimer := exec.Command("systemctl", "disable", "netclient-"+network+".timer")
}*/
cmdSysDaemonReload := exec.Command("systemctl","daemon-reload")/*&exec.Cmd {
Path: sysExec,
Args: []string{ sysExec, "daemon-reload"},
Stdout: os.Stdout,
Stderr: os.Stdout,
}*/
cmdSysResetFailed := exec.Command("systemctl","reset-failed")/*&exec.Cmd {
Path: sysExec,
Args: []string{ sysExec, "reset-failed"},
Stdout: os.Stdout,
Stderr: os.Stdout,
}*/
cmdSysStopTimer := exec.Command("systemctl", "stop", "netclient-"+network+".timer")/*&exec.Cmd {
Path: sysExec,
Args: []string{ sysExec, "stop", "netclient-"+network+".timer" },
Stdout: os.Stdout,
Stderr: os.Stdout,
}*/
cmdSysDisableTimer := exec.Command("systemctl", "disable", "netclient-"+network+".timer")/*&exec.Cmd {
Path: sysExec,
Args: []string{ sysExec, "disable", "netclient-"+network+".timer"},
Stdout: os.Stdout,
Stderr: os.Stdout,
}*/
//err = cmdSysStopService.Run()
if err != nil { if err != nil {
fmt.Println("Error stopping netclient@.service. Please investigate.") fmt.Println("Error stopping netclient@.service. Please investigate.")
fmt.Println(err) fmt.Println(err)
@@ -288,6 +275,52 @@ func RemoveSystemDServices(network string) error {
} }
func WipeLocal(network string) error{
cfg, err := config.ReadConfig(network)
if err != nil {
return err
}
nodecfg := cfg.Node
ifacename := nodecfg.Interface
//home, err := homedir.Dir()
home := "/etc/netclient"
_ = os.Remove(home + "/netconfig-" + network)
_ = os.Remove(home + "/nettoken-" + network)
_ = os.Remove(home + "/wgkey-" + network)
ipExec, err := exec.LookPath("ip")
if ifacename != "" {
cmdIPLinkDel := &exec.Cmd {
Path: ipExec,
Args: []string{ ipExec, "link", "del", ifacename },
Stdout: os.Stdout,
Stderr: os.Stdout,
}
err = cmdIPLinkDel.Run()
if err != nil {
fmt.Println(err)
}
if nodecfg.PostDown != "" {
runcmds := strings.Split(nodecfg.PostDown, "; ")
err = RunCmds(runcmds)
if err != nil {
fmt.Println("Error encountered running PostDown: " + err.Error())
}
}
}
return err
}
func HasNetwork(network string) bool{
return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
FileExists("/etc/netclient/netconfig-"+network)
}
func copy(src, dst string) (int64, error) { func copy(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src) sourceFileStat, err := os.Stat(src)
if err != nil { if err != nil {

View File

@@ -1,55 +1,318 @@
package main package main
import ( import (
"fmt" "errors"
"github.com/gravitl/netmaker/netclient/functions"
"golang.zx2c4.com/wireguard/wgctrl"
nodepb "github.com/gravitl/netmaker/grpc"
"flag"
"os"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "github.com/urfave/cli/v2"
"os"
"github.com/gravitl/netmaker/netclient/command"
"github.com/gravitl/netmaker/netclient/config"
"log" "log"
) )
const (
// name of the service
name = "netclient"
description = "Netmaker Daemon Service"
)
var password string
var network string
var server string
var accesskey string
var (
wgclient *wgctrl.Client
)
var (
wcclient nodepb.NodeServiceClient
)
func main() { func main() {
tpassword := flag.String("p", "changeme", "This node's password for accessing the server regularly") app := cli.NewApp()
taccesskey := flag.String("k", "badkey", "an access key generated by the server and used for one-time access (install only)") app.Name = "Netclient CLI"
taccesstoken := flag.String("t", "badtoken", "an token generated by the server and used for one-time access (install only)") app.Usage = "Netmaker's netclient agent and CLI. Used to perform interactions with Netmaker server and set local WireGuard config."
tname := flag.String("name", "noname", "give the node a name at runtime")
tserver := flag.String("s", "localhost:50051", "The location (including port) of the remote gRPC server.")
tnetwork := flag.String("n", "nonetwork", "The node network you are attempting to join.")
tdnsoff := flag.Bool("dnsoff", false, "DNS Mode. If true, netclient will not alter system dns. false by default.")
tpublicip := flag.String("ip4", "nopubip", "The node network you are attempting to join.")
tnoauto := flag.Bool("na", false, "No auto mode. If true, netmclient will not be installed as a system service and you will have to retrieve updates manually via checkin command.")
tipforward := flag.String("nf", "on", "No Forward mode. If true, netclient will not check for IP forwarding. This may break functionality")
command := flag.String("c", "required", "The command to run")
flag.Parse()
cliFlags := []cli.Flag{
&cli.StringFlag{
Name: "network",
Aliases: []string{"n"},
EnvVars: []string{"NETCLIENT_NETWORK"},
Value: "all",
Usage: "Network to perform specified action against.",
},
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
EnvVars: []string{"NETCLIENT_PASSWORD"},
Value: "badpassword",
Usage: "Password for authenticating with netmaker.",
},
&cli.StringFlag{
Name: "endpoint",
Aliases: []string{"e"},
EnvVars: []string{"NETCLIENT_ENDPOINT"},
Value: "",
Usage: "Reachable (usually public) address for WireGuard (not the private WG address).",
},
&cli.StringFlag{
Name: "macaddress",
Aliases: []string{"m"},
EnvVars: []string{"NETCLIENT_MACADDRESS"},
Value: "",
Usage: "Mac Address for this machine. Used as a unique identifier within Netmaker network.",
},
&cli.StringFlag{
Name: "publickey",
Aliases: []string{"pubkey"},
EnvVars: []string{"NETCLIENT_PUBLICKEY"},
Value: "",
Usage: "Public Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "privatekey",
Aliases: []string{"privkey"},
EnvVars: []string{"NETCLIENT_PRIVATEKEY"},
Value: "",
Usage: "Private Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "port",
EnvVars: []string{"NETCLIENT_PORT"},
Value: "",
Usage: "Port for WireGuard Interface.",
},
&cli.IntFlag{
Name: "keepalive",
EnvVars: []string{"NETCLIENT_KEEPALIVE"},
Value: 0,
Usage: "Default PersistentKeepAlive for Peers in WireGuard Interface.",
},
&cli.StringFlag{
Name: "name",
EnvVars: []string{"NETCLIENT_NAME"},
Value: "",
Usage: "Identifiable name for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "localaddress",
EnvVars: []string{"NETCLIENT_LOCALADDRESS"},
Value: "",
Usage: "Local address for machine. Can be used in place of Endpoint for machines on the same LAN.",
},
&cli.StringFlag{
Name: "address",
Aliases: []string{"a"},
EnvVars: []string{"NETCLIENT_ADDRESS"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "addressIPv6",
Aliases: []string{"a6"},
EnvVars: []string{"NETCLIENT_ADDRESSIPV6"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "interface",
Aliases: []string{"i"},
EnvVars: []string{"NETCLIENT_INTERFACE"},
Value: "",
Usage: "WireGuard local network interface name.",
},
&cli.StringFlag{
Name: "server",
Aliases: []string{"s"},
EnvVars: []string{"NETCLIENT_SERVER"},
Value: "",
Usage: "Address + GRPC Port (e.g. 1.2.3.4:50051) of Netmaker server.",
},
&cli.StringFlag{
Name: "key",
Aliases: []string{"k"},
EnvVars: []string{"NETCLIENT_ACCESSKEY"},
Value: "",
Usage: "Access Key for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
EnvVars: []string{"NETCLIENT_ACCESSTOKEN"},
Value: "",
Usage: "Access Token for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "localrange",
EnvVars: []string{"NETCLIENT_LOCALRANGE"},
Value: "",
Usage: "Local Range if network is local, for instance 192.168.1.0/24.",
},
&cli.StringFlag{
Name: "roaming",
EnvVars: []string{"NETCLIENT_ROAMING"},
Value: "on",
Usage: "Checks for changes in IP address during updates if 'on'. Stays static if 'off'. On by default.",
},
&cli.StringFlag{
Name: "dns",
EnvVars: []string{"NETCLIENT_DNS"},
Value: "",
Usage: "Sets private dns if 'on'. Ignores if 'off'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "islocal",
EnvVars: []string{"NETCLIENT_IS_LOCAL"},
Value: "",
Usage: "Sets endpoint to local address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "isdualstack",
EnvVars: []string{"NETCLIENT_IS_DUALSTACK"},
Value: "",
Usage: "Sets ipv6 address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "ipforwarding",
EnvVars: []string{"NETCLIENT_IPFORWARDING"},
Value: "on",
Usage: "Sets ip forwarding on if 'on'. Ignores if 'off'. On by default.",
},
&cli.StringFlag{
Name: "postup",
EnvVars: []string{"NETCLIENT_POSTUP"},
Value: "",
Usage: "Sets PostUp command for WireGuard.",
},
&cli.StringFlag{
Name: "postdown",
EnvVars: []string{"NETCLIENT_POSTDOWN"},
Value: "",
Usage: "Sets PostDown command for WireGuard.",
},
&cli.StringFlag{
Name: "daemon",
EnvVars: []string{"NETCLIENT_DAEMON"},
Value: "on",
Usage: "Installs daemon if 'on'. Ignores if 'off'. On by default.",
},
}
app.Commands = []*cli.Command{
{
Name: "register",
Usage: "Register with Netmaker Server for secure GRPC communications."
Flags: cliFlags,
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
if cfg.Server.Address == "" {
err = errors.New("No server address provided.")
return err
}
err = command.Register(cfg)
return err
},
},
{
Name: "join",
Usage: "Join a Netmaker network.",
Flags: cliFlags,
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
if cfg.Network == "all" {
err = errors.New("No network provided.")
return err
}
if cfg.Server.Address == "" {
err = errors.New("No server address provided.")
return err
}
err = command.Join(cfg)
return err
},
},
{
Name: "leave",
Usage: "Leave a Netmaker network.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Leave(cfg)
return err
},
},
{
Name: "checkin",
Usage: "Checks for local changes and then checks into the specified Netmaker network to ask about remote changes.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.CheckIn(cfg)
return err
},
},
{
Name: "push",
Usage: "Push configuration changes to server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Push(cfg)
return err
},
},
{
Name: "pull",
Usage: "Pull latest configuration and peers from server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Pull(cfg)
return err
},
},
{
Name: "status",
Usage: "Check network status.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Status(cfg)
return err
},
},
{
Name: "uninstall",
Usage: "Uninstall the netclient system service.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Uninstall(cfg)
return err
},
},
}
// start our application
getID := exec.Command("id", "-u") getID := exec.Command("id", "-u")
out, err := getID.Output() out, err := getID.Output()
@@ -73,122 +336,8 @@ func main() {
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.") log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
} }
switch *command { err = app.Run(os.Args)
case "getport":
portno, err := functions.GetFreePort(51821)
fmt.Printf("Port Number: %v", portno)
fmt.Println("")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
case "required":
fmt.Println("command flag 'c' is required. Pick one of |install|checkin|update|remove|")
os.Exit(1)
log.Fatal("Exiting")
case "install":
if *taccesstoken == "badtoken" && (*tnetwork == "nonetwork" || *tnetwork == "") {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
/*
if !*tnoforward {
forward := exec.Command("sysctl", "net.ipv4.ip_forward")
out, err := forward.Output()
if err != nil {
log.Fatal(err)
}
//s := strings.Split(string(out), " ", "\n")
s := strings.Fields(string(out))
if err != nil {
log.Fatal(err)
}
if s[2] != "1" {
log.Fatal("It is recommended to enable IP Forwarding. Current status is: " + s[2] + ", but should be 1. if you would like to run without IP Forwarding, re-run with flag '-nf true'")
}
}
*/
fmt.Println("Beginning agent installation.")
err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname, *tpublicip, *tdnsoff, *tipforward)
if err != nil {
fmt.Println("Error encountered while installing.")
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
fmt.Println("Error installing: ", err)
fmt.Println("Cleaning up (uninstall)")
err = functions.Remove(*tnetwork)
if err != nil {
fmt.Println("Error uninstalling: ", err)
fmt.Println("Wiping local.")
err = functions.WipeLocal(*tnetwork)
if err != nil {
fmt.Println("Error removing artifacts: ", err)
}
err = functions.RemoveSystemDServices(*tnetwork)
if err != nil {
fmt.Println("Error removing services: ", err)
}
}
os.Exit(1)
} else {
fmt.Println(err.Error())
os.Exit(1)
}
}
/*
case "service-install":
fmt.Println("Beginning service installation.")
err := functions.ConfigureSystemD()
if err != nil {
fmt.Println("Error installing service: ", err)
os.Exit(1)
}
case "service-uninstall":
fmt.Println("Beginning service uninstall.")
err := functions.RemoveSystemDServices()
if err != nil {
fmt.Println("Error installing service: ", err)
os.Exit(1)
}
*/
case "checkin":
if *tnetwork == "nonetwork" || *tnetwork == "" {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
fmt.Println("Beginning node check in for network " + *tnetwork)
err := functions.CheckIn(*tnetwork)
if err != nil {
fmt.Println("Error checking in: ", err)
os.Exit(1)
}
case "remove":
if *tnetwork == "nonetwork" || *tnetwork == "" {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
fmt.Println("Beginning node cleanup.")
err := functions.Remove(*tnetwork)
if err != nil {
/*
fmt.Println("Error uninstalling: ", err)
fmt.Println("Wiping local.")
err = functions.WipeLocal()
if err != nil {
fmt.Println("Error removing artifacts: ", err)
}
err = functions.RemoveSystemDServices()
if err != nil {
fmt.Println("Error removing services: ", err)
}
*/
fmt.Println("Error deleting node: ", err)
os.Exit(1)
}
default:
fmt.Println("You must select from the following commands: install|remove|checkin", err)
os.Exit(1)
}
fmt.Println("Command " + *command + " Executed Successfully")
} }

196
netclient/main.go.old Normal file
View File

@@ -0,0 +1,196 @@
package main
import (
"fmt"
"github.com/urfave/cli"
"github.com/gravitl/netmaker/netclient/functions"
"golang.zx2c4.com/wireguard/wgctrl"
nodepb "github.com/gravitl/netmaker/grpc"
"flag"
"os"
"os/exec"
"strconv"
"strings"
"log"
)
const (
// name of the service
name = "netclient"
description = "Netmaker Daemon Service"
)
var password string
var network string
var server string
var accesskey string
var (
wgclient *wgctrl.Client
)
var (
wcclient nodepb.NodeServiceClient
)
func main() {
tpassword := flag.String("p", "changeme", "This node's password for accessing the server regularly")
taccesskey := flag.String("k", "badkey", "an access key generated by the server and used for one-time access (install only)")
taccesstoken := flag.String("t", "badtoken", "an token generated by the server and used for one-time access (install only)")
tname := flag.String("name", "noname", "give the node a name at runtime")
tserver := flag.String("s", "localhost:50051", "The location (including port) of the remote gRPC server.")
tnetwork := flag.String("n", "nonetwork", "The node network you are attempting to join.")
tdnsoff := flag.Bool("dnsoff", false, "DNS Mode. If true, netclient will not alter system dns. false by default.")
tpublicip := flag.String("ip4", "nopubip", "The node network you are attempting to join.")
tnoauto := flag.Bool("na", false, "No auto mode. If true, netmclient will not be installed as a system service and you will have to retrieve updates manually via checkin command.")
tipforward := flag.String("nf", "on", "No Forward mode. If true, netclient will not check for IP forwarding. This may break functionality")
command := flag.String("c", "required", "The command to run")
flag.Parse()
getID := exec.Command("id", "-u")
out, err := getID.Output()
if err != nil {
log.Fatal(err)
}
id, err := strconv.Atoi(string(out[:len(out)-1]))
if err != nil {
log.Fatal(err)
}
if id != 0 {
log.Fatal("This program must be run with elevated privileges (sudo). This program installs a SystemD service and configures WireGuard and networking rules. Please re-run with sudo/root.")
}
_, err = exec.LookPath("wg")
if err != nil {
log.Println(err)
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
}
switch *command {
case "getport":
portno, err := functions.GetFreePort(51821)
fmt.Printf("Port Number: %v", portno)
fmt.Println("")
if err != nil {
log.Fatal(err)
}
case "required":
fmt.Println("command flag 'c' is required. Pick one of |install|checkin|update|remove|")
os.Exit(1)
log.Fatal("Exiting")
case "install":
if *taccesstoken == "badtoken" && (*tnetwork == "nonetwork" || *tnetwork == "") {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
/*
if !*tnoforward {
forward := exec.Command("sysctl", "net.ipv4.ip_forward")
out, err := forward.Output()
if err != nil {
log.Fatal(err)
}
//s := strings.Split(string(out), " ", "\n")
s := strings.Fields(string(out))
if err != nil {
log.Fatal(err)
}
if s[2] != "1" {
log.Fatal("It is recommended to enable IP Forwarding. Current status is: " + s[2] + ", but should be 1. if you would like to run without IP Forwarding, re-run with flag '-nf true'")
}
}
*/
fmt.Println("Beginning agent installation.")
err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname, *tpublicip, *tdnsoff, *tipforward)
if err != nil {
fmt.Println("Error encountered while installing.")
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
fmt.Println("Error installing: ", err)
fmt.Println("Cleaning up (uninstall)")
err = functions.Remove(*tnetwork)
if err != nil {
fmt.Println("Error uninstalling: ", err)
fmt.Println("Wiping local.")
err = functions.WipeLocal(*tnetwork)
if err != nil {
fmt.Println("Error removing artifacts: ", err)
}
err = functions.RemoveSystemDServices(*tnetwork)
if err != nil {
fmt.Println("Error removing services: ", err)
}
}
os.Exit(1)
} else {
fmt.Println(err.Error())
os.Exit(1)
}
}
/*
case "service-install":
fmt.Println("Beginning service installation.")
err := functions.ConfigureSystemD()
if err != nil {
fmt.Println("Error installing service: ", err)
os.Exit(1)
}
case "service-uninstall":
fmt.Println("Beginning service uninstall.")
err := functions.RemoveSystemDServices()
if err != nil {
fmt.Println("Error installing service: ", err)
os.Exit(1)
}
*/
case "checkin":
if *tnetwork == "nonetwork" || *tnetwork == "" {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
fmt.Println("Beginning node check in for network " + *tnetwork)
err := functions.CheckIn(*tnetwork)
if err != nil {
fmt.Println("Error checking in: ", err)
os.Exit(1)
}
case "remove":
if *tnetwork == "nonetwork" || *tnetwork == "" {
fmt.Println("Required, '-n'. No network provided. Exiting.")
os.Exit(1)
}
fmt.Println("Beginning node cleanup.")
err := functions.Remove(*tnetwork)
if err != nil {
/*
fmt.Println("Error uninstalling: ", err)
fmt.Println("Wiping local.")
err = functions.WipeLocal()
if err != nil {
fmt.Println("Error removing artifacts: ", err)
}
err = functions.RemoveSystemDServices()
if err != nil {
fmt.Println("Error removing services: ", err)
}
*/
fmt.Println("Error deleting node: ", err)
os.Exit(1)
}
default:
fmt.Println("You must select from the following commands: install|remove|checkin", err)
os.Exit(1)
}
fmt.Println("Command " + *command + " Executed Successfully")
}

View File

@@ -1,23 +1,132 @@
package functions package server
import ( import (
"fmt" "fmt"
"time"
"context" "context"
"io"
"strings"
"log" "log"
"net" "strings"
"strconv" "strconv"
"net"
"time"
"io"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/gravitl/netmaker/netclient/config" "github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/auth"
"github.com/gravitl/netmaker/netclient/local"
nodepb "github.com/gravitl/netmaker/grpc" nodepb "github.com/gravitl/netmaker/grpc"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
//homedir "github.com/mitchellh/go-homedir" //homedir "github.com/mitchellh/go-homedir"
) )
func getPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) { func GetNode(network string) nodepb.Node {
modcfg, err := config.ReadConfig(network)
if err != nil {
log.Fatalf("Error: %v", err)
}
nodecfg := modcfg.Node
var node nodepb.Node
node.Name = nodecfg.Name
node.Interface = nodecfg.Interface
node.Nodenetwork = nodecfg.Network
node.Localaddress = nodecfg.LocalAddress
node.Address = nodecfg.WGAddress
node.Address6 = nodecfg.WGAddress6
node.Listenport = nodecfg.Port
node.Keepalive = nodecfg.KeepAlive
node.Postup = nodecfg.PostUp
node.Postdown = nodecfg.PostDown
node.Publickey = nodecfg.PublicKey
node.Macaddress = nodecfg.MacAddress
node.Endpoint = nodecfg.Endpoint
node.Password = nodecfg.Password
if nodecfg.DNS == "on" {
node.Dnsoff = false
} else {
node.Dnsoff = true
}
if nodecfg.IsDualStack == "yes" {
node.Isdualstack = true
} else {
node.Isdualstack = false
}
if nodecfg.IsIngressGateway == "yes" {
node.Isingressgateway= true
} else {
node.Isingressgateway = false
}
return node
}
func RemoveNetwork(network string) error {
//need to implement checkin on server side
cfg, err := config.ReadConfig(network)
if err != nil {
return err
}
servercfg := cfg.Server
node := cfg.Node
fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
var wcclient nodepb.NodeServiceClient
var requestOpts grpc.DialOption
requestOpts = grpc.WithInsecure()
conn, err := grpc.Dial(servercfg.Address, requestOpts)
if err != nil {
log.Printf("Unable to establish client connection to " + servercfg.Address + ": %v", err)
//return err
}else {
wcclient = nodepb.NewNodeServiceClient(conn)
ctx := context.Background()
fmt.Println("Authenticating with GRPC Server")
ctx, err = auth.SetJWT(wcclient, network)
if err != nil {
//return err
log.Printf("Failed to authenticate: %v", err)
} else {
fmt.Println("Authenticated")
var header metadata.MD
_, err = wcclient.DeleteNode(
ctx,
&nodepb.DeleteNodeReq{
Macaddress: node.MacAddress,
NetworkName: node.Network,
},
grpc.Header(&header),
)
if err != nil {
log.Printf("Encountered error deleting node: %v", err)
fmt.Println(err)
} else {
fmt.Println("Deleted node " + node.MacAddress)
}
}
}
err = local.WipeLocal(network)
if err != nil {
log.Printf("Unable to wipe local config: %v", err)
}
err = local.RemoveSystemDServices(network)
if err != nil {
return err
log.Printf("Unable to remove systemd services: %v", err)
}
fmt.Printf("Please investigate any stated errors to ensure proper removal.")
fmt.Printf("Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator.")
return nil
}
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
//need to implement checkin on server side //need to implement checkin on server side
hasGateway := false hasGateway := false
var gateways []string var gateways []string
@@ -35,7 +144,6 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
} }
fmt.Println("Registering with GRPC Server")
requestOpts := grpc.WithInsecure() requestOpts := grpc.WithInsecure()
conn, err := grpc.Dial(server, requestOpts) conn, err := grpc.Dial(server, requestOpts)
if err != nil { if err != nil {
@@ -49,8 +157,7 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
Network: network, Network: network,
} }
ctx := context.Background() ctx := context.Background()
fmt.Println("Authenticating with GRPC Server") ctx, err = auth.SetJWT(wcclient, network)
ctx, err = SetJWT(wcclient, network)
if err != nil { if err != nil {
fmt.Println("Failed to authenticate.") fmt.Println("Failed to authenticate.")
return peers, hasGateway, gateways, err return peers, hasGateway, gateways, err
@@ -63,7 +170,6 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
fmt.Println(err) fmt.Println(err)
return nil, hasGateway, gateways, err return nil, hasGateway, gateways, err
} }
fmt.Println("Parsing peers response")
for { for {
res, err := stream.Recv() res, err := stream.Recv()
// If end of stream, break the loop // If end of stream, break the loop
@@ -88,11 +194,9 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
} }
if nodecfg.PublicKey == res.Peers.Publickey { if nodecfg.PublicKey == res.Peers.Publickey {
fmt.Println("Peer is self. Skipping")
continue continue
} }
if nodecfg.Endpoint == res.Peers.Endpoint { if nodecfg.Endpoint == res.Peers.Endpoint {
fmt.Println("Peer is self. Skipping")
continue continue
} }
@@ -149,8 +253,7 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
} }
if isIngressGateway { if isIngressGateway {
fmt.Println("Adding external peers...") extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
extPeers, err := getExtPeers(macaddress, network, server, dualstack)
if err == nil { if err == nil {
peers = append(peers, extPeers...) peers = append(peers, extPeers...)
fmt.Println("Added " + strconv.Itoa(len(extPeers)) + " external clients.") fmt.Println("Added " + strconv.Itoa(len(extPeers)) + " external clients.")
@@ -159,11 +262,10 @@ func getPeers(macaddress string, network string, server string, dualstack bool,
fmt.Println(err) fmt.Println(err)
} }
} }
fmt.Println("Finished parsing peers response")
return peers, hasGateway, gateways, err return peers, hasGateway, gateways, err
} }
func getExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) { func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
var peers []wgtypes.PeerConfig var peers []wgtypes.PeerConfig
var wcclient nodepb.NodeServiceClient var wcclient nodepb.NodeServiceClient
cfg, err := config.ReadConfig(network) cfg, err := config.ReadConfig(network)
@@ -186,8 +288,7 @@ func getExtPeers(macaddress string, network string, server string, dualstack boo
Network: network, Network: network,
} }
ctx := context.Background() ctx := context.Background()
fmt.Println("Authenticating with GRPC Server") ctx, err = auth.SetJWT(wcclient, network)
ctx, err = SetJWT(wcclient, network)
if err != nil { if err != nil {
fmt.Println("Failed to authenticate.") fmt.Println("Failed to authenticate.")
return peers, err return peers, err
@@ -200,7 +301,6 @@ func getExtPeers(macaddress string, network string, server string, dualstack boo
fmt.Println(err) fmt.Println(err)
return nil, err return nil, err
} }
fmt.Println("Parsing peers response")
for { for {
res, err := stream.Recv() res, err := stream.Recv()
// If end of stream, break the loop // If end of stream, break the loop
@@ -225,7 +325,6 @@ func getExtPeers(macaddress string, network string, server string, dualstack boo
} }
if nodecfg.PublicKey == res.Extpeers.Publickey { if nodecfg.PublicKey == res.Extpeers.Publickey {
fmt.Println("Peer is self. Skipping")
continue continue
} }

View File

@@ -0,0 +1,322 @@
package wireguard
import (
"fmt"
"context"
"io/ioutil"
"strings"
"log"
"net"
"os"
"os/exec"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
"github.com/gravitl/netmaker/netclient/auth"
"github.com/gravitl/netmaker/netclient/server"
nodepb "github.com/gravitl/netmaker/grpc"
"golang.zx2c4.com/wireguard/wgctrl"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
//homedir "github.com/mitchellh/go-homedir"
)
func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
ipExec, err := exec.LookPath("ip")
if err != nil {
return err
}
key, err := wgtypes.ParseKey(privkey)
if err != nil {
return err
}
wgclient, err := wgctrl.New()
//modcfg := config.Config
//modcfg.ReadConfig()
modcfg, err := config.ReadConfig(node.Nodenetwork)
if err != nil {
return err
}
nodecfg := modcfg.Node
servercfg := modcfg.Server
if err != nil {
log.Fatalf("failed to open client: %v", err)
}
defer wgclient.Close()
ifacename := node.Interface
if nodecfg.Interface != "" {
ifacename = nodecfg.Interface
} else if node.Interface != "" {
ifacename = node.Interface
} else {
log.Fatal("no interface to configure")
}
if node.Address == "" {
log.Fatal("no address to configure")
}
nameserver := servercfg.Address
nameserver = strings.Split(nameserver, ":")[0]
network := node.Nodenetwork
if nodecfg.Network != "" {
network = nodecfg.Network
} else if node.Nodenetwork != "" {
network = node.Nodenetwork
}
cmdIPDevLinkAdd := &exec.Cmd {
Path: ipExec,
Args: []string{ ipExec, "link", "add", "dev", ifacename, "type", "wireguard" },
Stdout: os.Stdout,
Stderr: os.Stdout,
}
cmdIPAddrAdd := &exec.Cmd {
Path: ipExec,
Args: []string{ ipExec, "address", "add", "dev", ifacename, node.Address+"/24"},
Stdout: os.Stdout,
Stderr: os.Stdout,
}
currentiface, err := net.InterfaceByName(ifacename)
if err != nil {
err = cmdIPDevLinkAdd.Run()
if err != nil && !strings.Contains(err.Error(), "exists") {
fmt.Println("Error creating interface")
//fmt.Println(err.Error())
//return err
}
}
match := false
addrs, _ := currentiface.Addrs()
for _, a := range addrs {
if strings.Contains(a.String(), node.Address){
match = true
}
}
if !match {
err = cmdIPAddrAdd.Run()
if err != nil {
fmt.Println("Error adding address")
//return err
}
}
var nodeport int
nodeport = int(node.Listenport)
//pubkey := privkey.PublicKey()
conf := wgtypes.Config{
PrivateKey: &key,
ListenPort: &nodeport,
ReplacePeers: true,
Peers: peers,
}
_, err = wgclient.Device(ifacename)
if err != nil {
if os.IsNotExist(err) {
fmt.Println("Device does not exist: ")
fmt.Println(err)
} else {
log.Fatalf("Unknown config error: %v", err)
}
}
err = wgclient.ConfigureDevice(ifacename, conf)
if err != nil {
if os.IsNotExist(err) {
fmt.Println("Device does not exist: ")
fmt.Println(err)
} else {
fmt.Printf("This is inconvenient: %v", err)
}
}
//=========DNS Setup==========\\
if nodecfg.DNS == "on" {
_, err := exec.LookPath("resolvectl")
if err != nil {
fmt.Println(err)
fmt.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
} else {
_, err = exec.Command("resolvectl", "domain", ifacename, "~"+network).Output()
if err != nil {
fmt.Println(err)
fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
} else {
_, err = exec.Command("resolvectl", "default-route", ifacename, "false").Output()
if err != nil {
fmt.Println(err)
fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
} else {
_, err = exec.Command("resolvectl", "dns", ifacename, nameserver).Output()
fmt.Println(err)
}
}
}
}
//=========End DNS Setup=======\\
cmdIPLinkUp := &exec.Cmd {
Path: ipExec,
Args: []string{ ipExec, "link", "set", "up", "dev", ifacename},
Stdout: os.Stdout,
Stderr: os.Stdout,
}
cmdIPLinkDown := &exec.Cmd {
Path: ipExec,
Args: []string{ ipExec, "link", "set", "down", "dev", ifacename},
Stdout: os.Stdout,
Stderr: os.Stdout,
}
err = cmdIPLinkDown.Run()
if nodecfg.PostDown != "" {
runcmds := strings.Split(nodecfg.PostDown, "; ")
err = local.RunCmds(runcmds)
if err != nil {
fmt.Println("Error encountered running PostDown: " + err.Error())
}
}
err = cmdIPLinkUp.Run()
if err != nil {
return err
}
if nodecfg.PostUp != "" {
runcmds := strings.Split(nodecfg.PostUp, "; ")
err = local.RunCmds(runcmds)
if err != nil {
fmt.Println("Error encountered running PostUp: " + err.Error())
}
}
if (hasGateway) {
for _, gateway := range gateways {
out, err := exec.Command(ipExec,"-4","route","add",gateway,"dev",ifacename).Output()
fmt.Println(string(out))
if err != nil {
fmt.Println("Error encountered adding gateway: " + err.Error())
}
}
}
if (node.Address6 != "" && node.Isdualstack) {
fmt.Println("Adding address: " + node.Address6)
out, err := exec.Command(ipExec, "address", "add", "dev", ifacename, node.Address6+"/64").Output()
if err != nil {
fmt.Println(out)
fmt.Println("Error encountered adding ipv6: " + err.Error())
}
}
return err
}
func SetWGKeyConfig(network string, serveraddr string) error {
ctx := context.Background()
var header metadata.MD
var wcclient nodepb.NodeServiceClient
var requestOpts grpc.DialOption
requestOpts = grpc.WithInsecure()
conn, err := grpc.Dial(serveraddr, requestOpts)
if err != nil {
fmt.Printf("Cant dial GRPC server: %v", err)
return err
}
wcclient = nodepb.NewNodeServiceClient(conn)
ctx, err = auth.SetJWT(wcclient, network)
if err != nil {
fmt.Printf("Failed to authenticate: %v", err)
return err
}
node := server.GetNode(network)
privatekey, err := wgtypes.GeneratePrivateKey()
if err != nil {
return err
}
privkeystring := privatekey.String()
publickey := privatekey.PublicKey()
node.Publickey = publickey.String()
err = StorePrivKey(privkeystring, network)
if err != nil {
return err
}
err = config.ModConfig(&node)
if err != nil {
return err
}
postnode := server.GetNode(network)
req := &nodepb.UpdateNodeReq{
Node: &postnode,
}
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
if err != nil {
return err
}
err = SetWGConfig(network)
if err != nil {
return err
log.Fatalf("Error: %v", err)
}
return err
}
func SetWGConfig(network string) error {
cfg, err := config.ReadConfig(network)
if err != nil {
return err
}
servercfg := cfg.Server
nodecfg := cfg.Node
node := server.GetNode(network)
peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, nodecfg.Network, servercfg.Address, node.Isdualstack, node.Isingressgateway)
if err != nil {
return err
}
privkey, err := RetrievePrivKey(network)
if err != nil {
return err
}
err = InitWireguard(&node, privkey, peers, hasGateway, gateways)
if err != nil {
return err
}
return err
}
func StorePrivKey(key string, network string) error{
d1 := []byte(key)
err := ioutil.WriteFile("/etc/netclient/wgkey-" + network, d1, 0644)
return err
}
func RetrievePrivKey(network string) (string, error) {
dat, err := ioutil.ReadFile("/etc/netclient/wgkey-" + network)
return string(dat), err
}

3
scripts/runmongo.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin.bash
docker volume create mongovol
docker run -d --name mongodb -v mongovol:/data/db --network host -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=mongopass mongo --bind_ip 0.0.0.0

View File

@@ -47,6 +47,21 @@ func GetConfig() config.ServerConfig {
return cfg return cfg
} }
func GetWGConfig() config.WG{
var cfg config.WG
if IsGRPCWireGuard() {
cfg.GRPCWireGuard = "on"
} else {
cfg.GRPCWireGuard = "off"
}
cfg.GRPCWGInterface = GetGRPCWGInterface()
cfg.GRPCWGAddress = GetGRPCWGAddress()
cfg.GRPCWGPort = GetGRPCWGPort()
cfg.GRPCWGEndpoint = GetGRPCHost()
return cfg
}
func GetAPIHost() string { func GetAPIHost() string {
serverhost := "127.0.0.1" serverhost := "127.0.0.1"
if os.Getenv("SERVER_HTTP_HOST") != "" { if os.Getenv("SERVER_HTTP_HOST") != "" {
@@ -67,6 +82,7 @@ func GetAPIPort() string {
} }
return apiport return apiport
} }
func GetGRPCHost() string { func GetGRPCHost() string {
serverhost := "127.0.0.1" serverhost := "127.0.0.1"
if os.Getenv("SERVER_GRPC_HOST") != "" { if os.Getenv("SERVER_GRPC_HOST") != "" {

View File

@@ -0,0 +1,85 @@
package servercfg
import (
"github.com/gravitl/netmaker/config"
"os"
)
func IsRegisterKeyRequired() bool {
isrequired := false
if os.Getenv("SERVER_GRPC_WG_KEYREQUIRED") != "" {
if os.Getenv("SERVER_GRPC_WG_KEYREQUIRED") == "yes" {
isrequired = true
}
} else if config.Config.WG.RegisterKeyRequired != "" {
if config.Config.WG.RegisterKeyRequired == "yes" {
isrequired = true
}
}
return isrequired
}
func IsGRPCWireGuard() bool {
iswg := true
if os.Getenv("SERVER_GRPC_WIREGUARD") != "" {
if os.Getenv("SERVER_GRPC_WIREGUARD") == "off" {
iswg = false
}
} else if config.Config.WG.GRPCWireGuard != "" {
if config.Config.WG.GRPCWireGuard == "off" {
iswg = false
}
}
return iswg
}
func GetGRPCWGInterface() string {
iface := "nm-grpc-wg"
if os.Getenv("SERVER_GRPC_WG_INTERFACE") != "" {
iface = os.Getenv("SERVER_GRPC_WG_INTERFACE")
} else if config.Config.WG.GRPCWGInterface != "" {
iface = config.Config.WG.GRPCWGInterface
}
return iface
}
func GetGRPCWGAddress() string {
address := "fd73:0093:84f3:a13d:0000:0000:0000:0001"
if os.Getenv("SERVER_GRPC_WG_ADDRESS") != "" {
address = os.Getenv("SERVER_GRPC_WG_ADDRESS")
} else if config.Config.WG.GRPCWGAddress != "" {
address = config.Config.WG.GRPCWGAddress
}
return address
}
func GetGRPCWGAddressRange() string {
address := "fd73:0093:84f3:a13d::/64"
if os.Getenv("SERVER_GRPC_WG_ADDRESS_RANGE") != "" {
address = os.Getenv("SERVER_GRPC_WG_ADDRESS_RANGE")
} else if config.Config.WG.GRPCWGAddressRange != "" {
address = config.Config.WG.GRPCWGAddressRange
}
return address
}
func GetGRPCWGPort() string {
port := "50555"
if os.Getenv("SERVER_GRPC_WG_PORT") != "" {
port = os.Getenv("SERVER_GRPC_WG_PORT")
} else if config.Config.WG.GRPCWGPort != "" {
port = config.Config.WG.GRPCWGPort
}
return port
}
func GetGRPCWGPubKey() string {
key := os.Getenv("SERVER_GRPC_WG_PUBKEY")
if config.Config.WG.GRPCWGPubKey != "" {
key = config.Config.WG.GRPCWGPubKey
}
return key
}
func GetGRPCWGPrivKey() string {
key := os.Getenv("SERVER_GRPC_WG_PRIVKEY")
if config.Config.WG.GRPCWGPrivKey != "" {
key = config.Config.WG.GRPCWGPrivKey
}
return key
}

View File

@@ -6,6 +6,8 @@ import (
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn" "github.com/gravitl/netmaker/mongoconn"
"github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/servercfg"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"io" "io"
"time" "time"
"context" "context"
@@ -59,6 +61,62 @@ func CreateDefaultNetwork() (bool, error) {
} }
func GetServerWGConf() (models.ServerClient, error) {
var server models.ServerClient
collection := mongoconn.Client.Database("netmaker").Collection("serverclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
filter := bson.M{"network": "comms", "isserver": "yes"}
err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&server)
defer cancel()
return server, err
}
func CreateCommsNetwork() (bool, error) {
fmt.Println("Creating GRPC network...")
iscreated := false
exists, err := functions.NetworkExists("comms")
if exists || err != nil {
fmt.Println("GRPC network already exists. Skipping...")
return true, nil
} else {
var network models.Network
network.NetID = "comms"
network.IsIPv6 = "yes"
network.IsIPv4 = "no"
network.IsGRPCHub = "yes"
network.AddressRange6 = servercfg.GetGRPCWGAddressRange()
network.DisplayName = "comms"
network.SetDefaults()
network.SetNodesLastModified()
network.SetNetworkLastModified()
network.KeyUpdateTimeStamp = time.Now().Unix()
priv := false
network.IsLocal = &priv
network.KeyUpdateTimeStamp = time.Now().Unix()
fmt.Println("Creating comms network.")
collection := mongoconn.Client.Database("netmaker").Collection("networks")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// insert our network into the network table
_, err = collection.InsertOne(ctx, network)
defer cancel()
}
if err == nil {
iscreated = true
}
return iscreated, err
}
func DownloadNetclient() error { func DownloadNetclient() error {
/* /*
// Get the data // Get the data

179
serverctl/wireguard.go Normal file
View File

@@ -0,0 +1,179 @@
package serverctl
import (
"os"
"log"
"context"
"time"
"net"
"strconv"
"errors"
"github.com/vishvananda/netlink"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"github.com/gravitl/netmaker/servercfg"
"github.com/gravitl/netmaker/functions"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mongoconn"
)
func InitServerWireGuard() error {
created, err := CreateCommsNetwork()
if !created {
return err
}
wgconfig := servercfg.GetWGConfig()
if !(wgconfig.GRPCWireGuard == "on") {
return errors.New("WireGuard not enabled on this server.")
}
ifaceSettings := netlink.NewLinkAttrs()
if wgconfig.GRPCWGInterface == "" {
return errors.New("No WireGuard Interface Name set.")
}
ifaceSettings.Name = wgconfig.GRPCWGInterface
wglink := &models.WireGuardLink{LinkAttrs: &ifaceSettings}
err = netlink.LinkAdd(wglink)
if err != nil {
if os.IsExist(err) {
log.Println("interface " + ifaceSettings.Name + " already exists")
log.Println("continuing setup using existing interface")
} else {
return err
}
}
address, err := netlink.ParseAddr(wgconfig.GRPCWGAddress + "/32")
if err != nil {
return err
}
err = netlink.AddrAdd(wglink, address)
if err != nil {
if os.IsExist(err) {
log.Println("address " + wgconfig.GRPCWGAddress + " already exists")
log.Println("continuing with existing setup")
} else {
return err
}
}
err = netlink.LinkSetUp(wglink)
if err != nil {
log.Println("could not bring up wireguard interface")
return err
}
var client models.ServerClient
client.PrivateKey = servercfg.GetGRPCWGPrivKey()
client.PublicKey = servercfg.GetGRPCWGPubKey()
client.ServerEndpoint = servercfg.GetGRPCHost()
client.Address6 = servercfg.GetGRPCWGAddress()
client.IsServer = "yes"
client.Network = "comms"
err = RegisterServer(client)
return err
}
func RegisterServer(client models.ServerClient) error {
if client.PrivateKey == "" {
privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil {
return err
}
client.PrivateKey = privateKey.String()
client.PublicKey = privateKey.PublicKey().String()
}
if client.Address == "" {
newAddress, err := functions.UniqueAddress6(client.Network)
if err != nil {
return err
}
client.Address6 = newAddress
}
if client.Network == "" { client.Network = "comms" }
client.ServerKey = client.PublicKey
collection := mongoconn.Client.Database("netmaker").Collection("serverclients")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// insert our network into the network table
_, err := collection.InsertOne(ctx, client)
defer cancel()
ReconfigureServerWireGuard()
return err
}
func ReconfigureServerWireGuard() error {
server, err := GetServerWGConf()
if err != nil {
return err
}
serverkey, err := wgtypes.ParseKey(server.PrivateKey)
if err != nil {
return err
}
serverport, err := strconv.Atoi(servercfg.GetGRPCWGPort())
if err != nil {
return err
}
peers, err := functions.GetPeersList("comms")
if err != nil {
return err
}
wgserver, err := wgctrl.New()
if err != nil {
return err
}
var serverpeers []wgtypes.PeerConfig
for _, peer := range peers {
pubkey, err := wgtypes.ParseKey(peer.PublicKey)
if err != nil {
return err
}
var peercfg wgtypes.PeerConfig
var allowedips []net.IPNet
if peer.Address != "" {
var peeraddr = net.IPNet{
IP: net.ParseIP(peer.Address),
Mask: net.CIDRMask(32, 32),
}
allowedips = append(allowedips, peeraddr)
}
if peer.Address6 != "" {
var addr6 = net.IPNet{
IP: net.ParseIP(peer.Address6),
Mask: net.CIDRMask(128, 128),
}
allowedips = append(allowedips, addr6)
}
peercfg = wgtypes.PeerConfig{
PublicKey: pubkey,
Endpoint: &net.UDPAddr{
IP: net.ParseIP(peer.Endpoint),
Port: int(peer.ListenPort),
},
ReplaceAllowedIPs: true,
AllowedIPs: allowedips,
}
serverpeers = append(serverpeers, peercfg)
}
wgconf := wgtypes.Config{
PrivateKey: &serverkey,
ListenPort: &serverport,
ReplacePeers: true,
Peers: serverpeers,
}
err = wgserver.ConfigureDevice(servercfg.GetGRPCWGInterface(), wgconf)
if err != nil {
return err
}
return nil
}