mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-21 16:09:59 +08:00
began refactoring of client
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
@@ -97,12 +98,17 @@ func grpcAuthorize(ctx context.Context) error {
|
||||
}
|
||||
|
||||
//Node authenticates using its password and retrieves a JWT for authorization.
|
||||
func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.LoginRequest) (*nodepb.LoginResponse, error) {
|
||||
func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
|
||||
//out := new(LoginResponse)
|
||||
macaddress := req.GetMacaddress()
|
||||
network := req.GetNetwork()
|
||||
password := req.GetPassword()
|
||||
var reqNode models.Node
|
||||
if err := json.Unmarshal([]byte(req.Data), &reqNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
macaddress := reqNode.MacAddress
|
||||
network := reqNode.Network
|
||||
password := reqNode.Password
|
||||
|
||||
var result models.NodeAuth
|
||||
|
||||
@@ -148,8 +154,9 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.LoginRequest)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &nodepb.LoginResponse{
|
||||
Accesstoken: tokenString,
|
||||
response := &nodepb.Object{
|
||||
Data: tokenString,
|
||||
Type: nodepb.ACCESS_TOKEN,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -16,9 +15,9 @@ import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func GetPeersList(networkName string) ([]models.PeersResponse, error) {
|
||||
func GetPeersList(networkName string) ([]models.Node, error) {
|
||||
|
||||
var peers []models.PeersResponse
|
||||
var peers []models.Node
|
||||
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
@@ -30,35 +29,31 @@ func GetPeersList(networkName string) ([]models.PeersResponse, error) {
|
||||
}
|
||||
for _, value := range collection {
|
||||
var node models.Node
|
||||
var peer models.PeersResponse
|
||||
var peer models.Node
|
||||
err := json.Unmarshal([]byte(value), &node)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
err = json.Unmarshal([]byte(value), &peer)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
if node.IsEgressGateway == "yes" {
|
||||
peer.EgressGatewayRanges = strings.Join(node.EgressGatewayRanges, ",")
|
||||
peer.EgressGatewayRanges = node.EgressGatewayRanges
|
||||
}
|
||||
if node.Network == networkName && node.IsPending != "yes" {
|
||||
if node.UDPHolePunch == "yes" && errN == nil && functions.CheckEndpoint(udppeers[peer.PublicKey]) {
|
||||
endpointstring := udppeers[peer.PublicKey]
|
||||
peer.PublicKey = node.PublicKey
|
||||
if node.UDPHolePunch == "yes" && errN == nil && functions.CheckEndpoint(udppeers[node.PublicKey]) {
|
||||
endpointstring := udppeers[node.PublicKey]
|
||||
endpointarr := strings.Split(endpointstring, ":")
|
||||
log.Println("got values:",endpointstring,endpointarr)
|
||||
log.Println("got values:", endpointstring, endpointarr)
|
||||
if len(endpointarr) == 2 {
|
||||
port, err := strconv.Atoi(endpointarr[1])
|
||||
if err == nil {
|
||||
log.Println("overriding:",endpointarr[0],int32(port))
|
||||
log.Println("overriding:", endpointarr[0], int32(port))
|
||||
peer.Endpoint = endpointarr[0]
|
||||
peer.ListenPort = int32(port)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Println("setting peer:",peer.PublicKey,peer.Endpoint,peer.ListenPort)
|
||||
log.Println("setting peer:", peer.PublicKey, peer.Endpoint, peer.ListenPort)
|
||||
peers = append(peers, peer)
|
||||
}
|
||||
}
|
||||
@@ -98,21 +93,38 @@ func GetExtPeersList(networkName string, macaddress string) ([]models.ExtPeersRe
|
||||
return peers, err
|
||||
}
|
||||
|
||||
func DeleteNode(macaddress string, network string) error {
|
||||
|
||||
key, err := functions.GetRecordKey(macaddress, network)
|
||||
if err != nil {
|
||||
/**
|
||||
* If being deleted by server, create a record in the DELETED_NODES_TABLE for the client to find
|
||||
* If being deleted by the client, delete completely
|
||||
*/
|
||||
func DeleteNode(key string, exterminate bool) error {
|
||||
var err error
|
||||
if !exterminate {
|
||||
args := strings.Split(key, "###")
|
||||
node, err := GetNode(args[0], args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node.Action = models.NODE_DELETE
|
||||
nodedata, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
if err := database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SetNetworkNodesLastModified(network)
|
||||
if servercfg.IsDNSMode() {
|
||||
err = SetDNS()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -136,6 +148,10 @@ func GetNode(macaddress string, network string) (models.Node, error) {
|
||||
}
|
||||
data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
|
||||
if err != nil {
|
||||
if data == "" {
|
||||
data, err = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
|
||||
err = json.Unmarshal([]byte(data), &node)
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(data), &node); err != nil {
|
||||
@@ -222,84 +238,6 @@ func NotifyNetworkCheck(networkName string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func NodeCheckIn(node models.Node, networkName string) (models.CheckInResponse, error) {
|
||||
|
||||
var response models.CheckInResponse
|
||||
|
||||
parentnetwork, err := functions.GetParentNetwork(networkName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%w; Couldnt retrieve Network "+networkName+": ", err)
|
||||
return response, err
|
||||
}
|
||||
|
||||
parentnode, err := GetNode(node.MacAddress, networkName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%w; Couldnt Get Node "+node.MacAddress, err)
|
||||
return response, err
|
||||
}
|
||||
|
||||
if parentnode.Name == "netmaker" {
|
||||
if NotifyNetworkCheck(networkName) {
|
||||
err := SetNetworkNodesLastModified(networkName)
|
||||
if err != nil {
|
||||
log.Println(err, "could not notify network to update peers")
|
||||
}
|
||||
}
|
||||
return models.CheckInResponse{
|
||||
Success:true,
|
||||
NeedPeerUpdate:true,
|
||||
NeedKeyUpdate: false,
|
||||
NeedConfigUpdate:false,
|
||||
NeedDelete:false,
|
||||
NodeMessage:"",
|
||||
IsPending:false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if parentnode.IsPending == "yes" {
|
||||
err = fmt.Errorf("%w; Node checking in is still pending: "+node.MacAddress, err)
|
||||
response.IsPending = true
|
||||
return response, err
|
||||
}
|
||||
|
||||
networklm := parentnetwork.NetworkLastModified
|
||||
peerslm := parentnetwork.NodesLastModified
|
||||
gkeyupdate := parentnetwork.KeyUpdateTimeStamp
|
||||
nkeyupdate := parentnode.KeyUpdateTimeStamp
|
||||
peerlistlm := parentnode.LastPeerUpdate
|
||||
parentnodelm := parentnode.LastModified
|
||||
parentnodelastcheckin := parentnode.LastCheckIn
|
||||
|
||||
if parentnodelastcheckin < parentnodelm {
|
||||
response.NeedConfigUpdate = true
|
||||
}
|
||||
|
||||
if parentnodelm < networklm {
|
||||
response.NeedConfigUpdate = true
|
||||
}
|
||||
if peerlistlm < peerslm {
|
||||
response.NeedPeerUpdate = true
|
||||
}
|
||||
if nkeyupdate < gkeyupdate {
|
||||
response.NeedKeyUpdate = true
|
||||
}
|
||||
|
||||
if time.Now().Unix() > parentnode.ExpirationDateTime {
|
||||
response.NeedDelete = true
|
||||
err = DeleteNode(node.MacAddress, networkName)
|
||||
} else {
|
||||
err = TimestampNode(parentnode, true, false, false)
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%w; Couldnt Timestamp Node: ", err)
|
||||
return response, err
|
||||
}
|
||||
}
|
||||
response.Success = true
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
func SetNetworkNodesLastModified(networkName string) error {
|
||||
|
||||
timestamp := time.Now().Unix()
|
||||
|
@@ -4,10 +4,11 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"log"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
@@ -232,17 +233,11 @@ func keyUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func KeyUpdate(netname string) (models.Network, error) {
|
||||
network, err := functions.GetParentNetwork(netname)
|
||||
err := functions.NetworkNodesUpdateKey(netname)
|
||||
if err != nil {
|
||||
return models.Network{}, err
|
||||
}
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
data, err := json.Marshal(&network)
|
||||
if err != nil {
|
||||
return models.Network{}, err
|
||||
}
|
||||
database.Insert(netname, string(data), database.NETWORKS_TABLE_NAME)
|
||||
return network, nil
|
||||
return models.Network{}, nil
|
||||
}
|
||||
|
||||
//Update a network
|
||||
|
@@ -2,83 +2,53 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type NodeServiceServer struct {
|
||||
nodepb.UnimplementedNodeServiceServer
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeReq) (*nodepb.ReadNodeRes, error) {
|
||||
func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
// convert string id (from proto) to mongoDB ObjectId
|
||||
macaddress := req.GetMacaddress()
|
||||
networkName := req.GetNetwork()
|
||||
network, _ := functions.GetParentNetwork(networkName)
|
||||
var node models.Node
|
||||
if err := json.Unmarshal([]byte(req.Data), &node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
macaddress := node.MacAddress
|
||||
networkName := node.Network
|
||||
|
||||
node, err := GetNode(macaddress, networkName)
|
||||
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Something went wrong: %v", err))
|
||||
log.Println("could not get node "+macaddress+" "+networkName, err)
|
||||
return nil, err
|
||||
}
|
||||
// Cast to ReadNodeRes type
|
||||
|
||||
response := &nodepb.ReadNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
Macaddress: node.MacAddress,
|
||||
Name: node.Name,
|
||||
Address: node.Address,
|
||||
Address6: node.Address6,
|
||||
Endpoint: node.Endpoint,
|
||||
Password: node.Password,
|
||||
Nodenetwork: node.Network,
|
||||
Interface: node.Interface,
|
||||
Localaddress: node.LocalAddress,
|
||||
Postdown: node.PostDown,
|
||||
Postup: node.PostUp,
|
||||
Checkininterval: node.CheckInInterval,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Ispending: node.IsPending == "yes",
|
||||
Isingressgateway: node.IsIngressGateway == "yes",
|
||||
Ingressgatewayrange: node.IngressGatewayRange,
|
||||
Publickey: node.PublicKey,
|
||||
Listenport: node.ListenPort,
|
||||
Keepalive: node.PersistentKeepalive,
|
||||
Islocal: network.IsLocal == "yes",
|
||||
Isdualstack: network.IsDualStack == "yes",
|
||||
Localrange: network.LocalRange,
|
||||
Udpholepunch: node.UDPHolePunch,
|
||||
},
|
||||
nodeData, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}
|
||||
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.Object) (*nodepb.Object, error) {
|
||||
// Get the protobuf node type from the protobuf request type
|
||||
// Essentially doing req.Node to access the struct with a nil check
|
||||
data := req.GetNode()
|
||||
// Now we have to convert this into a NodeItem type to convert into BSON
|
||||
node := models.Node{
|
||||
// ID: primitive.NilObjectID,
|
||||
MacAddress: data.GetMacaddress(),
|
||||
LocalAddress: data.GetLocaladdress(),
|
||||
Name: data.GetName(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
AccessKey: data.GetAccesskey(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
PersistentKeepalive: data.GetKeepalive(),
|
||||
Password: data.GetPassword(),
|
||||
Interface: data.GetInterface(),
|
||||
Network: data.GetNodenetwork(),
|
||||
PublicKey: data.GetPublickey(),
|
||||
ListenPort: data.GetListenport(),
|
||||
UDPHolePunch: data.GetUdpholepunch(),
|
||||
var node models.Node
|
||||
data := req.GetData()
|
||||
if err := json.Unmarshal([]byte(data), &node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Check to see if key is valid
|
||||
@@ -86,7 +56,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
||||
validKey := functions.IsKeyValid(node.Network, node.AccessKey)
|
||||
network, err := functions.GetParentNetwork(node.Network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find network: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !validKey {
|
||||
@@ -95,274 +65,125 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
||||
if network.AllowManualSignUp == "yes" {
|
||||
node.IsPending = "yes"
|
||||
} else {
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
fmt.Sprintf("Invalid key, and network does not allow no-key signups"),
|
||||
)
|
||||
return nil, errors.New("invalid key, and network does not allow no-key signups")
|
||||
}
|
||||
}
|
||||
|
||||
node, err = CreateNode(node, node.Network)
|
||||
|
||||
if err != nil {
|
||||
// return internal gRPC error to be handled later
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
fmt.Sprintf("Internal error: %v", err),
|
||||
)
|
||||
log.Println("could not create node on network " + node.Network + " (gRPC controller)")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeData, err := json.Marshal(&node)
|
||||
// return the node in a CreateNodeRes type
|
||||
response := &nodepb.CreateNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
Macaddress: node.MacAddress,
|
||||
Localaddress: node.LocalAddress,
|
||||
Name: node.Name,
|
||||
Address: node.Address,
|
||||
Address6: node.Address6,
|
||||
Endpoint: node.Endpoint,
|
||||
Password: node.Password,
|
||||
Interface: node.Interface,
|
||||
Nodenetwork: node.Network,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Ispending: node.IsPending == "yes",
|
||||
Publickey: node.PublicKey,
|
||||
Listenport: node.ListenPort,
|
||||
Keepalive: node.PersistentKeepalive,
|
||||
Islocal: network.IsLocal == "yes",
|
||||
Isdualstack: network.IsDualStack == "yes",
|
||||
Localrange: network.LocalRange,
|
||||
Udpholepunch: node.UDPHolePunch,
|
||||
},
|
||||
response := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}
|
||||
err = SetNetworkNodesLastModified(node.Network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) CheckIn(ctx context.Context, req *nodepb.CheckInReq) (*nodepb.CheckInRes, error) {
|
||||
// Get the protobuf node type from the protobuf request type
|
||||
// Essentially doing req.Node to access the struct with a nil check
|
||||
data := req.GetNode()
|
||||
//postchanges := req.GetPostchanges()
|
||||
// Now we have to convert this into a NodeItem type to convert into BSON
|
||||
node := models.Node{
|
||||
// ID: primitive.NilObjectID,
|
||||
MacAddress: data.GetMacaddress(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
Network: data.GetNodenetwork(),
|
||||
Password: data.GetPassword(),
|
||||
LocalAddress: data.GetLocaladdress(),
|
||||
ListenPort: data.GetListenport(),
|
||||
PersistentKeepalive: data.GetKeepalive(),
|
||||
PublicKey: data.GetPublickey(),
|
||||
UDPHolePunch: data.GetUdpholepunch(),
|
||||
SaveConfig: data.GetSaveconfig(),
|
||||
}
|
||||
|
||||
checkinresponse, err := NodeCheckIn(node, node.Network)
|
||||
|
||||
if err != nil {
|
||||
// return internal gRPC error to be handled later
|
||||
if checkinresponse == (models.CheckInResponse{}) || !checkinresponse.IsPending {
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
fmt.Sprintf("Internal error: %v", err),
|
||||
)
|
||||
}
|
||||
}
|
||||
// return the node in a CreateNodeRes type
|
||||
response := &nodepb.CheckInRes{
|
||||
Checkinresponse: &nodepb.CheckInResponse{
|
||||
Success: checkinresponse.Success,
|
||||
Needpeerupdate: checkinresponse.NeedPeerUpdate,
|
||||
Needdelete: checkinresponse.NeedDelete,
|
||||
Needconfigupdate: checkinresponse.NeedConfigUpdate,
|
||||
Needkeyupdate: checkinresponse.NeedKeyUpdate,
|
||||
Nodemessage: checkinresponse.NodeMessage,
|
||||
Ispending: checkinresponse.IsPending,
|
||||
},
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNodeReq) (*nodepb.UpdateNodeRes, error) {
|
||||
func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
// Get the node data from the request
|
||||
data := req.GetNode()
|
||||
// Now we have to convert this into a NodeItem type to convert into BSON
|
||||
newnode := models.Node{
|
||||
// ID: primitive.NilObjectID,
|
||||
MacAddress: data.GetMacaddress(),
|
||||
Name: data.GetName(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
LocalAddress: data.GetLocaladdress(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
Password: data.GetPassword(),
|
||||
PersistentKeepalive: data.GetKeepalive(),
|
||||
Network: data.GetNodenetwork(),
|
||||
Interface: data.GetInterface(),
|
||||
PostDown: data.GetPostdown(),
|
||||
PostUp: data.GetPostup(),
|
||||
PublicKey: data.GetPublickey(),
|
||||
ListenPort: data.GetListenport(),
|
||||
UDPHolePunch: data.GetUdpholepunch(),
|
||||
SaveConfig: data.GetSaveconfig(),
|
||||
var newnode models.Node
|
||||
if err := json.Unmarshal([]byte(req.GetData()), &newnode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert the Id string to a MongoDB ObjectId
|
||||
macaddress := newnode.MacAddress
|
||||
networkName := newnode.Network
|
||||
network, _ := functions.GetParentNetwork(networkName)
|
||||
|
||||
node, err := functions.GetNodeByMacAddress(networkName, macaddress)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = node.Update(&newnode)
|
||||
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.NotFound,
|
||||
fmt.Sprintf("Could not update node: %v", err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
return &nodepb.UpdateNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
Macaddress: newnode.MacAddress,
|
||||
Localaddress: newnode.LocalAddress,
|
||||
Name: newnode.Name,
|
||||
Address: newnode.Address,
|
||||
Address6: newnode.Address6,
|
||||
Endpoint: newnode.Endpoint,
|
||||
Password: newnode.Password,
|
||||
Interface: newnode.Interface,
|
||||
Postdown: newnode.PostDown,
|
||||
Postup: newnode.PostUp,
|
||||
Nodenetwork: newnode.Network,
|
||||
Ispending: newnode.IsPending == "yes",
|
||||
Publickey: newnode.PublicKey,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Listenport: newnode.ListenPort,
|
||||
Keepalive: newnode.PersistentKeepalive,
|
||||
Islocal: network.IsLocal == "yes",
|
||||
Isdualstack: network.IsDualStack == "yes",
|
||||
Localrange: network.LocalRange,
|
||||
Udpholepunch: newnode.UDPHolePunch,
|
||||
},
|
||||
nodeData, err := json.Marshal(&node)
|
||||
|
||||
return &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.DeleteNodeReq) (*nodepb.DeleteNodeRes, error) {
|
||||
macaddress := req.GetMacaddress()
|
||||
network := req.GetNetworkName()
|
||||
|
||||
err := DeleteNode(macaddress, network)
|
||||
func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
nodeID := req.GetData()
|
||||
|
||||
err := DeleteNode(nodeID, true)
|
||||
if err != nil {
|
||||
fmt.Println("Error deleting node.")
|
||||
fmt.Println(err)
|
||||
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find/delete node with mac address %s", macaddress))
|
||||
log.Println("Error deleting node (gRPC controller).")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("updating network last modified of " + req.GetNetworkName())
|
||||
err = SetNetworkNodesLastModified(req.GetNetworkName())
|
||||
if err != nil {
|
||||
fmt.Println("Error updating Network")
|
||||
fmt.Println(err)
|
||||
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
|
||||
}
|
||||
|
||||
return &nodepb.DeleteNodeRes{
|
||||
Success: true,
|
||||
return &nodepb.Object{
|
||||
Data: "success",
|
||||
Type: nodepb.STRING_TYPE,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.NodeService_GetPeersServer) error {
|
||||
func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
var node models.Node
|
||||
if err := json.Unmarshal([]byte(req.GetData()), &node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peers, err := GetPeersList(node.Network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peersData, err := json.Marshal(&peers)
|
||||
return &nodepb.Object{
|
||||
Data: string(peersData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}, nil
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Ext Peers (clients).NodeCheckIn
|
||||
* When a gateway node checks in, it pulls these peers to add to peers list in addition to normal network peers.
|
||||
*/
|
||||
func (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
||||
// Initiate a NodeItem type to write decoded data to
|
||||
//data := &models.PeersResponse{}
|
||||
// collection.Find returns a cursor for our (empty) query
|
||||
peers, err := GetPeersList(req.GetNetwork())
|
||||
|
||||
var reqNode models.Node
|
||||
if err := json.Unmarshal([]byte(req.Data), &reqNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
peers, err := GetExtPeersList(reqNode.Network, reqNode.MacAddress)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
// cursor.Next() returns a boolean, if false there are no more items and loop will break
|
||||
var extPeers []models.Node
|
||||
for i := 0; i < len(peers); i++ {
|
||||
|
||||
// If no error is found send node over stream
|
||||
stream.Send(&nodepb.GetPeersRes{
|
||||
Peers: &nodepb.PeersResponse{
|
||||
Address: peers[i].Address,
|
||||
Address6: peers[i].Address6,
|
||||
Endpoint: peers[i].Endpoint,
|
||||
Egressgatewayranges: peers[i].EgressGatewayRanges,
|
||||
Isegressgateway: peers[i].IsEgressGateway == "yes",
|
||||
Publickey: peers[i].PublicKey,
|
||||
Keepalive: peers[i].KeepAlive,
|
||||
Listenport: peers[i].ListenPort,
|
||||
Localaddress: peers[i].LocalAddress,
|
||||
},
|
||||
extPeers = append(extPeers, models.Node{
|
||||
Address: peers[i].Address,
|
||||
Address6: peers[i].Address6,
|
||||
Endpoint: peers[i].Endpoint,
|
||||
PublicKey: peers[i].PublicKey,
|
||||
PersistentKeepalive: peers[i].KeepAlive,
|
||||
ListenPort: peers[i].ListenPort,
|
||||
LocalAddress: peers[i].LocalAddress,
|
||||
})
|
||||
}
|
||||
|
||||
node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
|
||||
extData, err := json.Marshal(&extPeers)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = TimestampNode(node, false, true, false)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NodeServiceServer) GetExtPeers(req *nodepb.GetExtPeersReq, stream nodepb.NodeService_GetExtPeersServer) error {
|
||||
// Initiate a NodeItem type to write decoded data to
|
||||
//data := &models.PeersResponse{}
|
||||
// collection.Find returns a cursor for our (empty) query
|
||||
peers, err := GetExtPeersList(req.GetNetwork(), req.GetMacaddress())
|
||||
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
|
||||
}
|
||||
// cursor.Next() returns a boolean, if false there are no more items and loop will break
|
||||
for i := 0; i < len(peers); i++ {
|
||||
|
||||
// If no error is found send node over stream
|
||||
stream.Send(&nodepb.GetExtPeersRes{
|
||||
Extpeers: &nodepb.ExtPeersResponse{
|
||||
Address: peers[i].Address,
|
||||
Address6: peers[i].Address6,
|
||||
Endpoint: peers[i].Endpoint,
|
||||
Publickey: peers[i].PublicKey,
|
||||
Keepalive: peers[i].KeepAlive,
|
||||
Listenport: peers[i].ListenPort,
|
||||
Localaddress: peers[i].LocalAddress,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
|
||||
}
|
||||
|
||||
err = TimestampNode(node, false, true, false)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
return &nodepb.Object{
|
||||
Data: string(extData),
|
||||
Type: nodepb.EXT_PEER,
|
||||
}, nil
|
||||
}
|
||||
|
@@ -809,7 +809,7 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
||||
// get params
|
||||
var params = mux.Vars(r)
|
||||
|
||||
err := DeleteNode(params["macaddress"], params["network"])
|
||||
err := DeleteNode(params["macaddress"]+"###"+params["network"], false)
|
||||
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
|
@@ -183,7 +183,7 @@ func HasAdmin() (bool, error) {
|
||||
|
||||
collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return true, err
|
||||
}
|
||||
|
||||
for _, value := range collection { // filter for isadmin true
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
const NETWORKS_TABLE_NAME = "networks"
|
||||
const NODES_TABLE_NAME = "nodes"
|
||||
const DELETED_NODES_TABLE_NAME = "deletednodes"
|
||||
const USERS_TABLE_NAME = "users"
|
||||
const DNS_TABLE_NAME = "dns"
|
||||
const EXT_CLIENT_TABLE_NAME = "extclients"
|
||||
@@ -16,6 +17,10 @@ const INT_CLIENTS_TABLE_NAME = "intclients"
|
||||
const PEERS_TABLE_NAME = "peers"
|
||||
const DATABASE_FILENAME = "netmaker.db"
|
||||
|
||||
// == ERROR CONSTS ==
|
||||
const NO_RECORD = "no result found"
|
||||
const NO_RECORDS = "could not find any records"
|
||||
|
||||
var Database gorqlite.Connection
|
||||
|
||||
func InitializeDatabase() error {
|
||||
@@ -35,6 +40,7 @@ func InitializeDatabase() error {
|
||||
func createTables() {
|
||||
createTable(NETWORKS_TABLE_NAME)
|
||||
createTable(NODES_TABLE_NAME)
|
||||
createTable(DELETED_NODES_TABLE_NAME)
|
||||
createTable(USERS_TABLE_NAME)
|
||||
createTable(DNS_TABLE_NAME)
|
||||
createTable(EXT_CLIENT_TABLE_NAME)
|
||||
@@ -104,6 +110,9 @@ func FetchRecord(tableName string, key string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if results[key] == "" {
|
||||
return "", errors.New(NO_RECORD)
|
||||
}
|
||||
return results[key], nil
|
||||
}
|
||||
|
||||
@@ -119,6 +128,9 @@ func FetchRecords(tableName string) (map[string]string, error) {
|
||||
row.Scan(&key, &value)
|
||||
records[key] = value
|
||||
}
|
||||
if len(records) == 0 {
|
||||
return nil, errors.New(NO_RECORDS)
|
||||
}
|
||||
// log.Println(records)
|
||||
return records, nil
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func SetPeers(newPeers map[string]string, networkName string) bool {
|
||||
@@ -26,7 +27,6 @@ func GetPeers(networkName string) (map[string]string, error) {
|
||||
return currentDataMap, err
|
||||
}
|
||||
|
||||
|
||||
func PeersAreEqual(toCompare map[string]string, networkName string) bool {
|
||||
currentDataMap, err := GetPeers(networkName)
|
||||
if err != nil {
|
||||
@@ -36,9 +36,13 @@ func PeersAreEqual(toCompare map[string]string, networkName string) bool {
|
||||
return false
|
||||
}
|
||||
for k := range currentDataMap {
|
||||
if currentDataMap[k] != toCompare[k] {
|
||||
if toCompare[k] != currentDataMap[k] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsEmptyRecord(err error) bool {
|
||||
return strings.Contains(err.Error(), NO_RECORD) || strings.Contains(err.Error(), NO_RECORDS)
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
func CheckEndpoint(endpoint string) bool {
|
||||
endpointarr := strings.Split(endpoint,":")
|
||||
endpointarr := strings.Split(endpoint, ":")
|
||||
return net.ParseIP(endpointarr[0]) == nil
|
||||
}
|
||||
|
||||
@@ -200,9 +200,6 @@ func GetRecordKey(id string, network string) (string, error) {
|
||||
return id + "###" + network, nil
|
||||
}
|
||||
|
||||
//TODO: This is very inefficient (N-squared). Need to find a better way.
|
||||
//Takes a list of nodes in a network and iterates through
|
||||
//for each node, it gets a unique address. That requires checking against all other nodes once more
|
||||
func UpdateNetworkNodeAddresses(networkName string) error {
|
||||
|
||||
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||
@@ -235,6 +232,33 @@ func UpdateNetworkNodeAddresses(networkName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NetworkNodesUpdateKey(networkName string) error {
|
||||
|
||||
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, value := range collections {
|
||||
|
||||
var node models.Node
|
||||
err := json.Unmarshal([]byte(value), &node)
|
||||
if err != nil {
|
||||
fmt.Println("error in node address assignment!")
|
||||
return err
|
||||
}
|
||||
|
||||
node.Action = models.NODE_UPDATE_KEY
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
database.Insert(node.MacAddress, string(data), database.NODES_TABLE_NAME)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateNetworkLocalAddresses(networkName string) error {
|
||||
|
||||
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||
|
2036
grpc/node.pb.go
2036
grpc/node.pb.go
File diff suppressed because it is too large
Load Diff
165
grpc/node.proto
165
grpc/node.proto
@@ -3,159 +3,18 @@ package node;
|
||||
option go_package = "google.golang.org/protobuf/types/known/nodepb";
|
||||
|
||||
service NodeService {
|
||||
rpc Login(LoginRequest) returns (LoginResponse);
|
||||
rpc CreateNode(CreateNodeReq) returns (CreateNodeRes);
|
||||
rpc ReadNode(ReadNodeReq) returns (ReadNodeRes);
|
||||
rpc UpdateNode(UpdateNodeReq) returns (UpdateNodeRes);
|
||||
rpc DeleteNode(DeleteNodeReq) returns (DeleteNodeRes);
|
||||
rpc GetPeers(GetPeersReq) returns (stream GetPeersRes);
|
||||
rpc GetExtPeers(GetExtPeersReq) returns (stream GetExtPeersRes);
|
||||
rpc CheckIn(CheckInReq) returns (CheckInRes);
|
||||
rpc Login(Object) returns (Object);
|
||||
rpc CreateNode(Object) returns (Object);
|
||||
rpc ReadNode(Object) returns (Object);
|
||||
rpc UpdateNode(Object) returns (Object);
|
||||
rpc DeleteNode(Object) returns (Object);
|
||||
rpc GetPeers(Object) returns (Object);
|
||||
rpc GetExtPeers(Object) returns (Object);
|
||||
rpc CheckIn(Object) returns (Object);
|
||||
}
|
||||
|
||||
message LoginRequest {
|
||||
string macaddress = 1;
|
||||
string password = 2;
|
||||
string network = 3;
|
||||
message Object {
|
||||
string Data = 1;
|
||||
string Type = 2;
|
||||
string Metadata = 3;
|
||||
}
|
||||
|
||||
message LoginResponse { string accesstoken = 1; }
|
||||
|
||||
message Node {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
string address = 3;
|
||||
string address6 = 26;
|
||||
int32 listenport = 4;
|
||||
string publickey = 5;
|
||||
string endpoint = 6;
|
||||
string macaddress = 7;
|
||||
string password = 8;
|
||||
string nodenetwork = 9;
|
||||
bool ispending = 10;
|
||||
string postup = 11;
|
||||
string postdown = 12;
|
||||
int32 keepalive = 13;
|
||||
string saveconfig = 14;
|
||||
string accesskey = 15;
|
||||
string interface = 16;
|
||||
string lastcheckin = 17;
|
||||
string lastmodified = 18;
|
||||
int32 checkininterval = 19;
|
||||
string localaddress = 20;
|
||||
string postchanges = 21;
|
||||
string allowedips = 22;
|
||||
bool islocal = 23;
|
||||
bool isingressgateway = 28;
|
||||
string ingressgatewayrange = 29;
|
||||
bool isdualstack = 27;
|
||||
bool dnsoff = 24;
|
||||
string localrange = 25;
|
||||
string udpholepunch = 30;
|
||||
}
|
||||
|
||||
message CheckInResponse {
|
||||
bool success = 1;
|
||||
bool needpeerupdate = 2;
|
||||
bool needconfigupdate = 3;
|
||||
string nodemessage = 4;
|
||||
bool ispending = 5;
|
||||
bool needkeyupdate = 6;
|
||||
bool needdelete = 7;
|
||||
}
|
||||
|
||||
message PeersResponse {
|
||||
bool isegressgateway = 1;
|
||||
string egressgatewayranges = 2;
|
||||
string ingressgatewayrange = 9;
|
||||
string publickey = 5;
|
||||
string endpoint = 6;
|
||||
string address = 3;
|
||||
string address6 = 8;
|
||||
int32 listenport = 4;
|
||||
string localaddress = 7;
|
||||
int32 keepalive = 13;
|
||||
}
|
||||
|
||||
message ExtPeersResponse {
|
||||
string publickey = 5;
|
||||
string endpoint = 6;
|
||||
string address = 3;
|
||||
string address6 = 8;
|
||||
int32 listenport = 4;
|
||||
string localaddress = 7;
|
||||
int32 keepalive = 13;
|
||||
}
|
||||
|
||||
message Client {
|
||||
string privatekey = 1;
|
||||
string publickey = 2;
|
||||
string accesskey = 3;
|
||||
string address = 4;
|
||||
string address6 = 5;
|
||||
string serverwgendpoint = 6;
|
||||
string serverport = 7;
|
||||
string serverkey = 8;
|
||||
}
|
||||
|
||||
message CreateNodeReq {
|
||||
Node node = 1; // Node id blank
|
||||
}
|
||||
|
||||
message CreateNodeRes {
|
||||
Node node = 1; // Node id filled in
|
||||
}
|
||||
|
||||
message UpdateNodeReq {
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
message UpdateNodeRes {
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
message ReadNodeReq {
|
||||
string macaddress = 1;
|
||||
string network = 2;
|
||||
}
|
||||
|
||||
message ReadNodeRes {
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
message DeleteNodeReq {
|
||||
string macaddress = 1;
|
||||
string networkName = 2;
|
||||
}
|
||||
|
||||
message DeleteNodeRes {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
message GetPeersReq {
|
||||
string macaddress = 1;
|
||||
string network = 2;
|
||||
}
|
||||
|
||||
message GetExtPeersReq {
|
||||
string macaddress = 1;
|
||||
string network = 2;
|
||||
}
|
||||
|
||||
message GetPeersRes {
|
||||
PeersResponse peers = 1;
|
||||
}
|
||||
|
||||
message GetExtPeersRes {
|
||||
ExtPeersResponse extpeers = 1;
|
||||
}
|
||||
|
||||
message CheckInReq {
|
||||
Node node = 1;
|
||||
// bool postchanges = 2;
|
||||
}
|
||||
|
||||
message CheckInRes {
|
||||
CheckInResponse checkinresponse = 1;
|
||||
}
|
||||
|
||||
|
@@ -18,14 +18,14 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type NodeServiceClient interface {
|
||||
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
|
||||
CreateNode(ctx context.Context, in *CreateNodeReq, opts ...grpc.CallOption) (*CreateNodeRes, error)
|
||||
ReadNode(ctx context.Context, in *ReadNodeReq, opts ...grpc.CallOption) (*ReadNodeRes, error)
|
||||
UpdateNode(ctx context.Context, in *UpdateNodeReq, opts ...grpc.CallOption) (*UpdateNodeRes, error)
|
||||
DeleteNode(ctx context.Context, in *DeleteNodeReq, opts ...grpc.CallOption) (*DeleteNodeRes, error)
|
||||
GetPeers(ctx context.Context, in *GetPeersReq, opts ...grpc.CallOption) (NodeService_GetPeersClient, error)
|
||||
GetExtPeers(ctx context.Context, in *GetExtPeersReq, opts ...grpc.CallOption) (NodeService_GetExtPeersClient, error)
|
||||
CheckIn(ctx context.Context, in *CheckInReq, opts ...grpc.CallOption) (*CheckInRes, error)
|
||||
Login(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
CreateNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
ReadNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
UpdateNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
DeleteNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
GetPeers(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
GetExtPeers(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
CheckIn(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error)
|
||||
}
|
||||
|
||||
type nodeServiceClient struct {
|
||||
@@ -36,8 +36,8 @@ func NewNodeServiceClient(cc grpc.ClientConnInterface) NodeServiceClient {
|
||||
return &nodeServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) {
|
||||
out := new(LoginResponse)
|
||||
func (c *nodeServiceClient) Login(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/Login", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -45,8 +45,8 @@ func (c *nodeServiceClient) Login(ctx context.Context, in *LoginRequest, opts ..
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) CreateNode(ctx context.Context, in *CreateNodeReq, opts ...grpc.CallOption) (*CreateNodeRes, error) {
|
||||
out := new(CreateNodeRes)
|
||||
func (c *nodeServiceClient) CreateNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/CreateNode", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -54,8 +54,8 @@ func (c *nodeServiceClient) CreateNode(ctx context.Context, in *CreateNodeReq, o
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) ReadNode(ctx context.Context, in *ReadNodeReq, opts ...grpc.CallOption) (*ReadNodeRes, error) {
|
||||
out := new(ReadNodeRes)
|
||||
func (c *nodeServiceClient) ReadNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/ReadNode", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -63,8 +63,8 @@ func (c *nodeServiceClient) ReadNode(ctx context.Context, in *ReadNodeReq, opts
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) UpdateNode(ctx context.Context, in *UpdateNodeReq, opts ...grpc.CallOption) (*UpdateNodeRes, error) {
|
||||
out := new(UpdateNodeRes)
|
||||
func (c *nodeServiceClient) UpdateNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/UpdateNode", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -72,8 +72,8 @@ func (c *nodeServiceClient) UpdateNode(ctx context.Context, in *UpdateNodeReq, o
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) DeleteNode(ctx context.Context, in *DeleteNodeReq, opts ...grpc.CallOption) (*DeleteNodeRes, error) {
|
||||
out := new(DeleteNodeRes)
|
||||
func (c *nodeServiceClient) DeleteNode(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/DeleteNode", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -81,72 +81,26 @@ func (c *nodeServiceClient) DeleteNode(ctx context.Context, in *DeleteNodeReq, o
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) GetPeers(ctx context.Context, in *GetPeersReq, opts ...grpc.CallOption) (NodeService_GetPeersClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &NodeService_ServiceDesc.Streams[0], "/node.NodeService/GetPeers", opts...)
|
||||
func (c *nodeServiceClient) GetPeers(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/GetPeers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &nodeServiceGetPeersClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type NodeService_GetPeersClient interface {
|
||||
Recv() (*GetPeersRes, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type nodeServiceGetPeersClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *nodeServiceGetPeersClient) Recv() (*GetPeersRes, error) {
|
||||
m := new(GetPeersRes)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) GetExtPeers(ctx context.Context, in *GetExtPeersReq, opts ...grpc.CallOption) (NodeService_GetExtPeersClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &NodeService_ServiceDesc.Streams[1], "/node.NodeService/GetExtPeers", opts...)
|
||||
func (c *nodeServiceClient) GetExtPeers(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/GetExtPeers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &nodeServiceGetExtPeersClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type NodeService_GetExtPeersClient interface {
|
||||
Recv() (*GetExtPeersRes, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type nodeServiceGetExtPeersClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *nodeServiceGetExtPeersClient) Recv() (*GetExtPeersRes, error) {
|
||||
m := new(GetExtPeersRes)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) CheckIn(ctx context.Context, in *CheckInReq, opts ...grpc.CallOption) (*CheckInRes, error) {
|
||||
out := new(CheckInRes)
|
||||
func (c *nodeServiceClient) CheckIn(ctx context.Context, in *Object, opts ...grpc.CallOption) (*Object, error) {
|
||||
out := new(Object)
|
||||
err := c.cc.Invoke(ctx, "/node.NodeService/CheckIn", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -158,14 +112,14 @@ func (c *nodeServiceClient) CheckIn(ctx context.Context, in *CheckInReq, opts ..
|
||||
// All implementations must embed UnimplementedNodeServiceServer
|
||||
// for forward compatibility
|
||||
type NodeServiceServer interface {
|
||||
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
||||
CreateNode(context.Context, *CreateNodeReq) (*CreateNodeRes, error)
|
||||
ReadNode(context.Context, *ReadNodeReq) (*ReadNodeRes, error)
|
||||
UpdateNode(context.Context, *UpdateNodeReq) (*UpdateNodeRes, error)
|
||||
DeleteNode(context.Context, *DeleteNodeReq) (*DeleteNodeRes, error)
|
||||
GetPeers(*GetPeersReq, NodeService_GetPeersServer) error
|
||||
GetExtPeers(*GetExtPeersReq, NodeService_GetExtPeersServer) error
|
||||
CheckIn(context.Context, *CheckInReq) (*CheckInRes, error)
|
||||
Login(context.Context, *Object) (*Object, error)
|
||||
CreateNode(context.Context, *Object) (*Object, error)
|
||||
ReadNode(context.Context, *Object) (*Object, error)
|
||||
UpdateNode(context.Context, *Object) (*Object, error)
|
||||
DeleteNode(context.Context, *Object) (*Object, error)
|
||||
GetPeers(context.Context, *Object) (*Object, error)
|
||||
GetExtPeers(context.Context, *Object) (*Object, error)
|
||||
CheckIn(context.Context, *Object) (*Object, error)
|
||||
mustEmbedUnimplementedNodeServiceServer()
|
||||
}
|
||||
|
||||
@@ -173,28 +127,28 @@ type NodeServiceServer interface {
|
||||
type UnimplementedNodeServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedNodeServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
|
||||
func (UnimplementedNodeServiceServer) Login(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) CreateNode(context.Context, *CreateNodeReq) (*CreateNodeRes, error) {
|
||||
func (UnimplementedNodeServiceServer) CreateNode(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateNode not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) ReadNode(context.Context, *ReadNodeReq) (*ReadNodeRes, error) {
|
||||
func (UnimplementedNodeServiceServer) ReadNode(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ReadNode not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) UpdateNode(context.Context, *UpdateNodeReq) (*UpdateNodeRes, error) {
|
||||
func (UnimplementedNodeServiceServer) UpdateNode(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateNode not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) DeleteNode(context.Context, *DeleteNodeReq) (*DeleteNodeRes, error) {
|
||||
func (UnimplementedNodeServiceServer) DeleteNode(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteNode not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) GetPeers(*GetPeersReq, NodeService_GetPeersServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method GetPeers not implemented")
|
||||
func (UnimplementedNodeServiceServer) GetPeers(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPeers not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) GetExtPeers(*GetExtPeersReq, NodeService_GetExtPeersServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method GetExtPeers not implemented")
|
||||
func (UnimplementedNodeServiceServer) GetExtPeers(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetExtPeers not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) CheckIn(context.Context, *CheckInReq) (*CheckInRes, error) {
|
||||
func (UnimplementedNodeServiceServer) CheckIn(context.Context, *Object) (*Object, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CheckIn not implemented")
|
||||
}
|
||||
func (UnimplementedNodeServiceServer) mustEmbedUnimplementedNodeServiceServer() {}
|
||||
@@ -211,7 +165,7 @@ func RegisterNodeServiceServer(s grpc.ServiceRegistrar, srv NodeServiceServer) {
|
||||
}
|
||||
|
||||
func _NodeService_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(LoginRequest)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -223,13 +177,13 @@ func _NodeService_Login_Handler(srv interface{}, ctx context.Context, dec func(i
|
||||
FullMethod: "/node.NodeService/Login",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).Login(ctx, req.(*LoginRequest))
|
||||
return srv.(NodeServiceServer).Login(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_CreateNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateNodeReq)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -241,13 +195,13 @@ func _NodeService_CreateNode_Handler(srv interface{}, ctx context.Context, dec f
|
||||
FullMethod: "/node.NodeService/CreateNode",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).CreateNode(ctx, req.(*CreateNodeReq))
|
||||
return srv.(NodeServiceServer).CreateNode(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_ReadNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadNodeReq)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -259,13 +213,13 @@ func _NodeService_ReadNode_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
FullMethod: "/node.NodeService/ReadNode",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).ReadNode(ctx, req.(*ReadNodeReq))
|
||||
return srv.(NodeServiceServer).ReadNode(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_UpdateNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateNodeReq)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -277,13 +231,13 @@ func _NodeService_UpdateNode_Handler(srv interface{}, ctx context.Context, dec f
|
||||
FullMethod: "/node.NodeService/UpdateNode",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).UpdateNode(ctx, req.(*UpdateNodeReq))
|
||||
return srv.(NodeServiceServer).UpdateNode(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_DeleteNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteNodeReq)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -295,55 +249,49 @@ func _NodeService_DeleteNode_Handler(srv interface{}, ctx context.Context, dec f
|
||||
FullMethod: "/node.NodeService/DeleteNode",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).DeleteNode(ctx, req.(*DeleteNodeReq))
|
||||
return srv.(NodeServiceServer).DeleteNode(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_GetPeers_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(GetPeersReq)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
func _NodeService_GetPeers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return srv.(NodeServiceServer).GetPeers(m, &nodeServiceGetPeersServer{stream})
|
||||
}
|
||||
|
||||
type NodeService_GetPeersServer interface {
|
||||
Send(*GetPeersRes) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type nodeServiceGetPeersServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *nodeServiceGetPeersServer) Send(m *GetPeersRes) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _NodeService_GetExtPeers_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(GetExtPeersReq)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
if interceptor == nil {
|
||||
return srv.(NodeServiceServer).GetPeers(ctx, in)
|
||||
}
|
||||
return srv.(NodeServiceServer).GetExtPeers(m, &nodeServiceGetExtPeersServer{stream})
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/node.NodeService/GetPeers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).GetPeers(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
type NodeService_GetExtPeersServer interface {
|
||||
Send(*GetExtPeersRes) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type nodeServiceGetExtPeersServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *nodeServiceGetExtPeersServer) Send(m *GetExtPeersRes) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
func _NodeService_GetExtPeers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(NodeServiceServer).GetExtPeers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/node.NodeService/GetExtPeers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).GetExtPeers(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_CheckIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CheckInReq)
|
||||
in := new(Object)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -355,7 +303,7 @@ func _NodeService_CheckIn_Handler(srv interface{}, ctx context.Context, dec func
|
||||
FullMethod: "/node.NodeService/CheckIn",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).CheckIn(ctx, req.(*CheckInReq))
|
||||
return srv.(NodeServiceServer).CheckIn(ctx, req.(*Object))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -387,22 +335,19 @@ var NodeService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "DeleteNode",
|
||||
Handler: _NodeService_DeleteNode_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPeers",
|
||||
Handler: _NodeService_GetPeers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetExtPeers",
|
||||
Handler: _NodeService_GetExtPeers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CheckIn",
|
||||
Handler: _NodeService_CheckIn_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "GetPeers",
|
||||
Handler: _NodeService_GetPeers_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "GetExtPeers",
|
||||
Handler: _NodeService_GetExtPeers_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "grpc/node.proto",
|
||||
}
|
||||
|
6
grpc/types.go
Normal file
6
grpc/types.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package nodepb
|
||||
|
||||
const STRING_TYPE = "string"
|
||||
const NODE_TYPE = "node"
|
||||
const EXT_PEER = "extpeer"
|
||||
const ACCESS_TOKEN = "accesstoken"
|
5
main.go
5
main.go
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@@ -34,8 +34,7 @@ func initialize() { // Client Mode Prereq Check
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("database successfully connected.")
|
||||
cmd := exec.Command("id", "-u")
|
||||
output, err := cmd.Output()
|
||||
output, err := local.RunCmd("id -u")
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
|
||||
|
@@ -157,7 +157,7 @@ func (network *Network) IsNetworkNameUnique() (bool, error) {
|
||||
|
||||
dbs, err := GetNetworks()
|
||||
|
||||
if err != nil {
|
||||
if err != nil && !database.IsEmptyRecord(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -299,29 +299,29 @@ func (currentNetwork *Network) Update(newNetwork *Network) (bool, bool, error) {
|
||||
|
||||
func (network *Network) SetNetworkNodesLastModified() error {
|
||||
|
||||
timestamp := time.Now().Unix()
|
||||
timestamp := time.Now().Unix()
|
||||
|
||||
network.NodesLastModified = timestamp
|
||||
data, err := json.Marshal(&network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
network.NodesLastModified = timestamp
|
||||
data, err := json.Marshal(&network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetNetwork(networkname string) (Network, error) {
|
||||
|
||||
var network Network
|
||||
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
|
||||
if err != nil {
|
||||
return network, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(networkData), &network); err != nil {
|
||||
return Network{}, err
|
||||
}
|
||||
return network, nil
|
||||
var network Network
|
||||
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
|
||||
if err != nil {
|
||||
return network, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(networkData), &network); err != nil {
|
||||
return Network{}, err
|
||||
}
|
||||
return network, nil
|
||||
}
|
||||
|
127
models/node.go
127
models/node.go
@@ -16,48 +16,82 @@ import (
|
||||
const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
const TEN_YEARS_IN_SECONDS = 300000000
|
||||
|
||||
// == ACTIONS == (can only be set by GRPC)
|
||||
const NODE_UPDATE_KEY = "updatekey"
|
||||
const NODE_DELETE = "delete"
|
||||
const NODE_IS_PENDING = "pending"
|
||||
|
||||
var seededRand *rand.Rand = rand.New(
|
||||
rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
//node struct
|
||||
type Node struct {
|
||||
ID string `json:"id,omitempty" bson:"id,omitempty"`
|
||||
Address string `json:"address" bson:"address" validate:"omitempty,ipv4"`
|
||||
Address6 string `json:"address6" bson:"address6" validate:"omitempty,ipv6"`
|
||||
LocalAddress string `json:"localaddress" bson:"localaddress" validate:"omitempty,ip"`
|
||||
Name string `json:"name" bson:"name" validate:"omitempty,max=12,in_charset"`
|
||||
ListenPort int32 `json:"listenport" bson:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
|
||||
PublicKey string `json:"publickey" bson:"publickey" validate:"required,base64"`
|
||||
Endpoint string `json:"endpoint" bson:"endpoint" validate:"required,ip"`
|
||||
PostUp string `json:"postup" bson:"postup"`
|
||||
PostDown string `json:"postdown" bson:"postdown"`
|
||||
AllowedIPs []string `json:"allowedips" bson:"allowedips"`
|
||||
PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
|
||||
SaveConfig string `json:"saveconfig" bson:"saveconfig" validate:"checkyesorno"`
|
||||
AccessKey string `json:"accesskey" bson:"accesskey"`
|
||||
Interface string `json:"interface" bson:"interface"`
|
||||
LastModified int64 `json:"lastmodified" bson:"lastmodified"`
|
||||
KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
|
||||
ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime"`
|
||||
LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate"`
|
||||
LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin"`
|
||||
MacAddress string `json:"macaddress" bson:"macaddress" validate:"required,mac,macaddress_unique"`
|
||||
CheckInInterval int32 `json:"checkininterval" bson:"checkininterval"`
|
||||
Password string `json:"password" bson:"password" validate:"required,min=6"`
|
||||
Network string `json:"network" bson:"network" validate:"network_exists"`
|
||||
IsPending string `json:"ispending" bson:"ispending"`
|
||||
IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway"`
|
||||
IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges"`
|
||||
IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange"`
|
||||
PostChanges string `json:"postchanges" bson:"postchanges"`
|
||||
StaticIP string `json:"staticip" bson:"staticip"`
|
||||
StaticPubKey string `json:"staticpubkey" bson:"staticpubkey"`
|
||||
UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" validate:"checkyesorno"`
|
||||
Address string `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
|
||||
Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
|
||||
LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
|
||||
Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=12,in_charset"`
|
||||
ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
|
||||
PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
|
||||
Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
|
||||
PostUp string `json:"postup" bson:"postup" yaml:"postup"`
|
||||
PostDown string `json:"postdown" bson:"postdown" yaml:"postdown"`
|
||||
AllowedIPs []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
|
||||
PersistentKeepalive int32 `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
|
||||
SaveConfig string `json:"saveconfig" bson:"saveconfig" yaml:"saveconfig" validate:"checkyesorno"`
|
||||
AccessKey string `json:"accesskey" bson:"accesskey" yaml:"accesskey"`
|
||||
Interface string `json:"interface" bson:"interface" yaml:"interface"`
|
||||
LastModified int64 `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"`
|
||||
KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp" yaml:"keyupdatetimestamp"`
|
||||
ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
|
||||
LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
|
||||
LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
|
||||
MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,mac,macaddress_unique"`
|
||||
CheckInInterval int32 `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"`
|
||||
Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`
|
||||
Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"`
|
||||
IsPending string `json:"ispending" bson:"ispending" yaml:"ispending"`
|
||||
IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway"`
|
||||
IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||
IngressGatewayRange string `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
|
||||
StaticIP string `json:"staticip" bson:"staticip" yaml:"staticip"`
|
||||
StaticPubKey string `json:"staticpubkey" bson:"staticpubkey" yaml:"staticpubkey"`
|
||||
UDPHolePunch string `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
|
||||
PullChanges string `json:"pullchanges" bson:"pullchanges" yaml:"pullchanges" validate:"checkyesorno"`
|
||||
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
|
||||
IsDualStack string `json:"isdualstack" bson:"isdualstack" yaml:"isdualstack" validate:"checkyesorno"`
|
||||
Action string `json:"action" bson:"action" yaml:"action"`
|
||||
IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
|
||||
LocalRange string `json:"localrange" bson:"localrange" yaml:"localrange"`
|
||||
Roaming string `json:"roaming" bson:"roaming" yaml:"roaming" validate:"checkyesorno"`
|
||||
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
|
||||
}
|
||||
|
||||
func (node *Node) SetIPForwardingDefault() {
|
||||
if node.IPForwarding == "" {
|
||||
node.IPForwarding = "no"
|
||||
}
|
||||
}
|
||||
|
||||
func (node *Node) SetIsLocalDefault() {
|
||||
if node.IsLocal == "" {
|
||||
node.IsLocal = "no"
|
||||
}
|
||||
}
|
||||
|
||||
func (node *Node) SetDNSOnDefault() {
|
||||
if node.DNSOn == "" {
|
||||
node.DNSOn = "no"
|
||||
}
|
||||
}
|
||||
|
||||
func (node *Node) SetIsDualStackDefault() {
|
||||
if node.IsDualStack == "" {
|
||||
node.IsDualStack = "no"
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:
|
||||
//Not sure if below two methods are necessary. May want to revisit
|
||||
func (node *Node) SetLastModified() {
|
||||
node.LastModified = time.Now().Unix()
|
||||
}
|
||||
@@ -141,7 +175,10 @@ func (node *Node) SetDefaults() {
|
||||
}
|
||||
}
|
||||
node.CheckInInterval = parentNetwork.DefaultCheckInInterval
|
||||
|
||||
node.SetIPForwardingDefault()
|
||||
node.SetDNSOnDefault()
|
||||
node.SetIsLocalDefault()
|
||||
node.SetIsDualStackDefault()
|
||||
node.SetLastModified()
|
||||
node.SetDefaultName()
|
||||
node.SetLastCheckIn()
|
||||
@@ -260,8 +297,24 @@ func (newNode *Node) Fill(currentNode *Node) {
|
||||
if newNode.UDPHolePunch == "" {
|
||||
newNode.UDPHolePunch = currentNode.SaveConfig
|
||||
}
|
||||
|
||||
newNode.PostChanges = "no"
|
||||
if newNode.DNSOn == "" {
|
||||
newNode.DNSOn = currentNode.DNSOn
|
||||
}
|
||||
if newNode.IsDualStack == "" {
|
||||
newNode.IsDualStack = currentNode.IsDualStack
|
||||
}
|
||||
if newNode.IsLocal == "" {
|
||||
newNode.IsLocal = currentNode.IsLocal
|
||||
}
|
||||
if newNode.IPForwarding == "" {
|
||||
newNode.IPForwarding = currentNode.IPForwarding
|
||||
}
|
||||
if newNode.Roaming == "" {
|
||||
newNode.Roaming = currentNode.Roaming
|
||||
}
|
||||
if newNode.Action == "" {
|
||||
newNode.Action = currentNode.Action
|
||||
}
|
||||
}
|
||||
|
||||
func (currentNode *Node) Update(newNode *Node) error {
|
||||
|
@@ -1,69 +1,96 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"fmt"
|
||||
// "os"
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/codes"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
|
||||
// "os"
|
||||
"context"
|
||||
"io/ioutil"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// CreateJWT func will used to create the JWT while signing in and signing out
|
||||
func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) {
|
||||
//home, err := os.UserHomeDir()
|
||||
home := "/etc/netclient"
|
||||
tokentext, err := ioutil.ReadFile(home + "/nettoken-"+network)
|
||||
if err != nil {
|
||||
err = AutoLogin(client, network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong with Auto Login: %v", err))
|
||||
}
|
||||
tokentext, err = ioutil.ReadFile(home + "/nettoken-"+network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong: %v", err))
|
||||
}
|
||||
//home, err := os.UserHomeDir()
|
||||
home := "/etc/netclient"
|
||||
tokentext, err := ioutil.ReadFile(home + "/nettoken-" + network)
|
||||
if err != nil {
|
||||
err = AutoLogin(client, network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong with Auto Login: %v", err))
|
||||
}
|
||||
token := string(tokentext)
|
||||
tokentext, err = ioutil.ReadFile(home + "/nettoken-" + network)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong: %v", err))
|
||||
}
|
||||
}
|
||||
token := string(tokentext)
|
||||
|
||||
// Anything linked to this variable will transmit request headers.
|
||||
md := metadata.New(map[string]string{"authorization": token})
|
||||
ctx := context.Background()
|
||||
ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
return ctx, nil
|
||||
// Anything linked to this variable will transmit request headers.
|
||||
md := metadata.New(map[string]string{"authorization": token})
|
||||
ctx := context.Background()
|
||||
ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func AutoLogin(client nodepb.NodeServiceClient, network string) error {
|
||||
//home, err := os.UserHomeDir()
|
||||
home := "/etc/netclient"
|
||||
//nodecfg := config.Config.Node
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
login := &nodepb.LoginRequest{
|
||||
Password: cfg.Node.Password,
|
||||
Macaddress: cfg.Node.MacAddress,
|
||||
Network: network,
|
||||
}
|
||||
// RPC call
|
||||
res, err := client.Login(context.TODO(), login)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tokenstring := []byte(res.Accesstoken)
|
||||
err = ioutil.WriteFile(home + "/nettoken-"+network, tokenstring, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
//home, err := os.UserHomeDir()
|
||||
home := "/etc/netclient"
|
||||
//nodecfg := config.Config.Node
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pass, err := RetrieveSecret(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node := models.Node{
|
||||
Password: pass,
|
||||
MacAddress: cfg.Node.MacAddress,
|
||||
Network: network,
|
||||
}
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
login := &nodepb.Object{
|
||||
Data: string(data),
|
||||
}
|
||||
// RPC call
|
||||
res, err := client.Login(context.TODO(), login)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tokenstring := []byte(res.Data)
|
||||
err = ioutil.WriteFile(home+"/nettoken-"+network, tokenstring, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func StoreSecret(key string, network string) error {
|
||||
d1 := []byte(key)
|
||||
err := ioutil.WriteFile("/etc/netclient/secret-"+network, d1, 0644)
|
||||
return err
|
||||
}
|
||||
|
||||
func RetrieveSecret(network string) (string, error) {
|
||||
dat, err := ioutil.ReadFile("/etc/netclient/secret-" + network)
|
||||
return string(dat), err
|
||||
}
|
||||
|
||||
type Configuration struct {
|
||||
MacAddress string
|
||||
Password string
|
||||
Password string
|
||||
}
|
||||
|
@@ -1,32 +1,28 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/netclient/functions"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"log"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/functions"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
)
|
||||
|
||||
var (
|
||||
wgclient *wgctrl.Client
|
||||
wgclient *wgctrl.Client
|
||||
)
|
||||
|
||||
var (
|
||||
wcclient nodepb.NodeServiceClient
|
||||
wcclient nodepb.NodeServiceClient
|
||||
)
|
||||
|
||||
func Register(cfg config.GlobalConfig) error {
|
||||
err := functions.Register(cfg)
|
||||
return err
|
||||
}
|
||||
func Join(cfg config.ClientConfig, privateKey string) error {
|
||||
|
||||
func Join(cfg config.ClientConfig) error {
|
||||
|
||||
err := functions.JoinNetwork(cfg)
|
||||
err := functions.JoinNetwork(cfg, privateKey)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
|
||||
log.Println("Error installing: ", err)
|
||||
@@ -38,15 +34,15 @@ func Join(cfg config.ClientConfig) error {
|
||||
}
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
err = local.RemoveSystemDServices(cfg.Network)
|
||||
if err != nil {
|
||||
log.Println("Error removing services: ", err)
|
||||
}
|
||||
err = local.RemoveSystemDServices(cfg.Network)
|
||||
if err != nil {
|
||||
log.Println("Error removing services: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
log.Println("joined " + cfg.Network)
|
||||
log.Println("joined " + cfg.Network)
|
||||
if cfg.Daemon != "off" {
|
||||
err = functions.InstallDaemon(cfg)
|
||||
}
|
||||
@@ -54,74 +50,70 @@ func Join(cfg config.ClientConfig) error {
|
||||
}
|
||||
|
||||
func CheckIn(cfg config.ClientConfig) error {
|
||||
if cfg.Network == "all" || cfg.Network == "" {
|
||||
if cfg.Network == "all" || cfg.Network == "" {
|
||||
log.Println("Required, '-n'. No network provided. Exiting.")
|
||||
os.Exit(1)
|
||||
}
|
||||
err := functions.CheckIn(cfg)
|
||||
if err != nil {
|
||||
log.Println("Error checking in: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
err := functions.CheckConfig(cfg)
|
||||
return err
|
||||
}
|
||||
|
||||
func Leave(cfg config.ClientConfig) error {
|
||||
err := functions.LeaveNetwork(cfg.Network)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
log.Println("Error attempting to leave network " + cfg.Network)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func Push(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
if cfg.Network == "all" {
|
||||
log.Println("No network selected. Running Push for all networks.")
|
||||
networks, err := functions.GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
err = functions.Push(network)
|
||||
if err != nil {
|
||||
log.Printf("Error pushing network configs for " + network + " network: ", err)
|
||||
} else {
|
||||
log.Println("pushed network config for " + network)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
err = functions.Push(cfg.Network)
|
||||
}
|
||||
log.Println("Completed pushing network configs to remote server.")
|
||||
return err
|
||||
}
|
||||
|
||||
func Pull(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
var err error
|
||||
if cfg.Network == "all" {
|
||||
log.Println("No network selected. Running Pull for all networks.")
|
||||
log.Println("No network selected. Running Push for all networks.")
|
||||
networks, err := functions.GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
err = functions.Pull(network)
|
||||
err = functions.Push(network)
|
||||
if err != nil {
|
||||
log.Printf("Error pulling network config for " + network + " network: ", err)
|
||||
log.Printf("Error pushing network configs for "+network+" network: ", err)
|
||||
} else {
|
||||
log.Println("pushed network config for " + network)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
err = functions.Push(cfg.Network)
|
||||
}
|
||||
log.Println("Completed pushing network configs to remote server.")
|
||||
return err
|
||||
}
|
||||
|
||||
func Pull(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
if cfg.Network == "all" {
|
||||
log.Println("No network selected. Running Pull for all networks.")
|
||||
networks, err := functions.GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
_, err = functions.Pull(network, true)
|
||||
if err != nil {
|
||||
log.Printf("Error pulling network config for "+network+" network: ", err)
|
||||
} else {
|
||||
log.Println("pulled network config for " + network)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
err = functions.Pull(cfg.Network)
|
||||
_, err = functions.Pull(cfg.Network, true)
|
||||
}
|
||||
log.Println("Completed pulling network and peer configs.")
|
||||
return err
|
||||
return err
|
||||
}
|
||||
|
||||
func List(cfg config.ClientConfig) error {
|
||||
@@ -133,10 +125,9 @@ func Uninstall(cfg config.GlobalConfig) error {
|
||||
log.Println("Uninstalling netclient")
|
||||
err := functions.Uninstall()
|
||||
err = functions.Unregister(cfg)
|
||||
return err
|
||||
return err
|
||||
}
|
||||
func Unregister(cfg config.GlobalConfig) error {
|
||||
err := functions.Unregister(cfg)
|
||||
return err
|
||||
err := functions.Unregister(cfg)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/urfave/cli/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
@@ -22,7 +21,7 @@ type GlobalConfig struct {
|
||||
|
||||
type ClientConfig struct {
|
||||
Server ServerConfig `yaml:"server"`
|
||||
Node NodeConfig `yaml:"node"`
|
||||
Node models.Node `yaml:"node"`
|
||||
Network string `yaml:"network"`
|
||||
Daemon string `yaml:"daemon"`
|
||||
OperatingSystem string `yaml:"operatingsystem"`
|
||||
@@ -36,45 +35,6 @@ type ServerConfig struct {
|
||||
GRPCWireGuard string `yaml:"grpcwg"`
|
||||
}
|
||||
|
||||
type ListConfig struct {
|
||||
Name string `yaml:"name"`
|
||||
Interface string `yaml:"interface"`
|
||||
PrivateIPv4 string `yaml:"wgaddress"`
|
||||
PrivateIPv6 string `yaml:"wgaddress6"`
|
||||
PublicEndpoint string `yaml:"endpoint"`
|
||||
}
|
||||
|
||||
type NodeConfig struct {
|
||||
Name string `yaml:"name"`
|
||||
Interface string `yaml:"interface"`
|
||||
Network string `yaml:"network"`
|
||||
Password string `yaml:"password"`
|
||||
MacAddress string `yaml:"macaddress"`
|
||||
LocalAddress string `yaml:"localaddress"`
|
||||
WGAddress string `yaml:"wgaddress"`
|
||||
WGAddress6 string `yaml:"wgaddress6"`
|
||||
Roaming string `yaml:"roaming"`
|
||||
DNS string `yaml:"dns"`
|
||||
IsLocal string `yaml:"islocal"`
|
||||
IsDualStack string `yaml:"isdualstack"`
|
||||
IsIngressGateway string `yaml:"isingressgateway"`
|
||||
LocalRange string `yaml:"localrange"`
|
||||
PostUp string `yaml:"postup"`
|
||||
PostDown string `yaml:"postdown"`
|
||||
Port int32 `yaml:"port"`
|
||||
KeepAlive int32 `yaml:"keepalive"`
|
||||
PublicKey string `yaml:"publickey"`
|
||||
ServerPubKey string `yaml:"serverpubkey"`
|
||||
PrivateKey string `yaml:"privatekey"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
PostChanges string `yaml:"postchanges"`
|
||||
StaticIP string `yaml:"staticip"`
|
||||
StaticPubKey string `yaml:"staticpubkey"`
|
||||
IPForwarding string `yaml:"ipforwarding"`
|
||||
UDPHolePunch string `yaml:"udpholepunch"`
|
||||
SaveConfig string `yaml:"saveconfig"`
|
||||
}
|
||||
|
||||
//reading in the env file
|
||||
func Write(config *ClientConfig, network string) error {
|
||||
if network == "" {
|
||||
@@ -232,6 +192,7 @@ func (config *ClientConfig) ReadConfig() {
|
||||
fmt.Println(err)
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
config.Node.SetID()
|
||||
//config = cfg
|
||||
}
|
||||
}
|
||||
@@ -289,10 +250,10 @@ func ModGlobalConfig(cfg models.IntClient) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func ModConfig(node *nodepb.Node) error {
|
||||
network := node.Nodenetwork
|
||||
func ModConfig(node *models.Node) error {
|
||||
network := node.Network
|
||||
if network == "" {
|
||||
return errors.New("No Network Provided")
|
||||
return errors.New("no network provided")
|
||||
}
|
||||
var modconfig ClientConfig
|
||||
var err error
|
||||
@@ -303,90 +264,23 @@ func ModConfig(node *nodepb.Node) error {
|
||||
}
|
||||
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.Udpholepunch != "" {
|
||||
nodecfg.UDPHolePunch = node.Udpholepunch
|
||||
}
|
||||
if node.Saveconfig != "" {
|
||||
nodecfg.SaveConfig = node.Saveconfig
|
||||
}
|
||||
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
|
||||
modconfig.Node.Fill(node)
|
||||
err = Write(&modconfig, network)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetCLIConfig(c *cli.Context) (ClientConfig, error) {
|
||||
func GetCLIConfig(c *cli.Context) (ClientConfig, string, 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
|
||||
return cfg, "", err
|
||||
}
|
||||
var accesstoken models.AccessToken
|
||||
if err := json.Unmarshal(tokenbytes, &accesstoken); err != nil {
|
||||
log.Println("error converting token json to object", tokenbytes)
|
||||
return cfg, err
|
||||
return cfg, "", err
|
||||
}
|
||||
|
||||
if accesstoken.ServerConfig.APIConnString != "" {
|
||||
@@ -454,87 +348,25 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, error) {
|
||||
cfg.Node.Password = c.String("password")
|
||||
cfg.Node.MacAddress = c.String("macaddress")
|
||||
cfg.Node.LocalAddress = c.String("localaddress")
|
||||
cfg.Node.WGAddress = c.String("address")
|
||||
cfg.Node.WGAddress6 = c.String("addressIPV6")
|
||||
cfg.Node.Address = c.String("address")
|
||||
cfg.Node.Address6 = c.String("addressIPV6")
|
||||
cfg.Node.Roaming = c.String("roaming")
|
||||
cfg.Node.DNS = c.String("dns")
|
||||
cfg.Node.DNSOn = c.String("dns")
|
||||
cfg.Node.IsLocal = c.String("islocal")
|
||||
cfg.Node.IsDualStack = c.String("isdualstack")
|
||||
cfg.Node.PostUp = c.String("postup")
|
||||
cfg.Node.PostDown = c.String("postdown")
|
||||
cfg.Node.Port = int32(c.Int("port"))
|
||||
cfg.Node.KeepAlive = int32(c.Int("keepalive"))
|
||||
cfg.Node.ListenPort = int32(c.Int("port"))
|
||||
cfg.Node.PersistentKeepalive = int32(c.Int("keepalive"))
|
||||
cfg.Node.PublicKey = c.String("publickey")
|
||||
cfg.Node.PrivateKey = c.String("privatekey")
|
||||
privateKey := c.String("privatekey")
|
||||
cfg.Node.Endpoint = c.String("endpoint")
|
||||
cfg.Node.IPForwarding = c.String("ipforwarding")
|
||||
cfg.OperatingSystem = c.String("operatingsystem")
|
||||
cfg.Daemon = c.String("daemon")
|
||||
cfg.Node.UDPHolePunch = c.String("udpholepunch")
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func GetCLIConfigRegister(c *cli.Context) (GlobalConfig, error) {
|
||||
var cfg GlobalConfig
|
||||
if c.String("token") != "" {
|
||||
tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))
|
||||
if err != nil {
|
||||
log.Println("error decoding token")
|
||||
return cfg, err
|
||||
}
|
||||
var accesstoken models.AccessToken
|
||||
if err := json.Unmarshal(tokenbytes, &accesstoken); err != nil {
|
||||
log.Println("error converting token json to object", tokenbytes)
|
||||
return cfg, err
|
||||
}
|
||||
cfg.GRPCWireGuard = accesstoken.WG.GRPCWireGuard
|
||||
cfg.Client.ServerPrivateAddress = accesstoken.WG.GRPCWGAddress
|
||||
cfg.Client.ServerGRPCPort = accesstoken.WG.GRPCWGPort
|
||||
if err != nil {
|
||||
log.Println("error decoding token grpcserver")
|
||||
return cfg, err
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("error decoding token apiserver")
|
||||
return cfg, err
|
||||
}
|
||||
if accesstoken.ServerConfig.APIConnString != "" {
|
||||
cfg.Client.ServerPublicEndpoint = accesstoken.ServerConfig.APIConnString
|
||||
} else {
|
||||
cfg.Client.ServerPublicEndpoint = accesstoken.ServerConfig.APIHost
|
||||
if accesstoken.ServerConfig.APIPort != "" {
|
||||
cfg.Client.ServerAPIPort = accesstoken.ServerConfig.APIPort
|
||||
}
|
||||
}
|
||||
cfg.Client.ServerWGPort = accesstoken.WG.GRPCWGPort
|
||||
cfg.Client.ServerKey = accesstoken.ClientConfig.Key
|
||||
cfg.Client.ServerKey = accesstoken.WG.GRPCWGPubKey
|
||||
|
||||
if c.String("grpcserver") != "" {
|
||||
cfg.Client.ServerPrivateAddress = c.String("grpcserver")
|
||||
}
|
||||
if c.String("apiserver") != "" {
|
||||
cfg.Client.ServerPublicEndpoint = c.String("apiserver")
|
||||
}
|
||||
if c.String("pubkey") != "" {
|
||||
cfg.Client.ServerKey = c.String("pubkey")
|
||||
}
|
||||
if c.String("network") != "all" {
|
||||
cfg.Client.Network = c.String("network")
|
||||
}
|
||||
} else {
|
||||
cfg.Client.ServerPrivateAddress = c.String("grpcserver")
|
||||
cfg.Client.ServerPublicEndpoint = c.String("apiserver")
|
||||
cfg.Client.ServerKey = c.String("key")
|
||||
cfg.Client.Network = c.String("network")
|
||||
}
|
||||
cfg.Client.Address = c.String("address")
|
||||
cfg.Client.Address6 = c.String("addressIPV6")
|
||||
cfg.Client.PublicKey = c.String("pubkey")
|
||||
cfg.Client.PrivateKey = c.String("privkey")
|
||||
|
||||
return cfg, nil
|
||||
return cfg, privateKey, nil
|
||||
}
|
||||
|
||||
func ReadConfig(network string) (*ClientConfig, error) {
|
||||
@@ -596,3 +428,15 @@ func FileExists(f string) bool {
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func GetNode(network string) models.Node {
|
||||
|
||||
modcfg, err := ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
var node models.Node
|
||||
node.Fill(&modcfg.Node)
|
||||
|
||||
return node
|
||||
}
|
||||
|
@@ -1,389 +1,284 @@
|
||||
package functions
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/credentials"
|
||||
"crypto/tls"
|
||||
"context"
|
||||
"strings"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
"os/exec"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"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"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/metadata"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
func CheckIn(cliconf config.ClientConfig) error {
|
||||
network := cliconf.Network
|
||||
node := server.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
servercfg := cfg.Server
|
||||
log.Println("Checking into server at " + servercfg.GRPCAddress)
|
||||
|
||||
setupcheck := true
|
||||
func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.ClientConfig, network string) bool {
|
||||
ipchange := false
|
||||
|
||||
if nodecfg.DNS == "on" || cliconf.Node.DNS == "on" {
|
||||
log.Println("setting dns")
|
||||
ifacename := node.Interface
|
||||
nameserver := servercfg.CoreDNSAddr
|
||||
network := node.Nodenetwork
|
||||
_ = local.UpdateDNS(ifacename, network, nameserver)
|
||||
}
|
||||
|
||||
if !(nodecfg.IPForwarding == "off") {
|
||||
out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.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 {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
||||
}
|
||||
var err error
|
||||
if node.Roaming == "yes" {
|
||||
if node.IsLocal == "no" {
|
||||
log.Println("Checking to see if public addresses have changed")
|
||||
extIP, err := getPublicIP()
|
||||
if err != nil {
|
||||
log.Println("error encountered checking ip addresses:", err)
|
||||
}
|
||||
if node.Endpoint != extIP && extIP != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
node.Endpoint + " to " + extIP)
|
||||
log.Println("Updating address")
|
||||
node.Endpoint = extIP
|
||||
ipchange = true
|
||||
}
|
||||
intIP, err := getPrivateAddr()
|
||||
if err != nil {
|
||||
log.Println("error encountered checking ip addresses:", err)
|
||||
}
|
||||
if node.LocalAddress != intIP && intIP != "" {
|
||||
log.Println("Local Address has changed from " +
|
||||
node.LocalAddress + " to " + intIP)
|
||||
log.Println("Updating address")
|
||||
node.LocalAddress = intIP
|
||||
ipchange = true
|
||||
}
|
||||
} else {
|
||||
log.Println("Checking to see if local addresses have changed")
|
||||
localIP, err := getLocalIP(node.LocalRange)
|
||||
if err != nil {
|
||||
log.Println("error encountered checking ip addresses:", err)
|
||||
}
|
||||
if node.Endpoint != localIP && localIP != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
node.Endpoint + " to " + localIP)
|
||||
log.Println("Updating address")
|
||||
node.Endpoint = localIP
|
||||
node.LocalAddress = localIP
|
||||
ipchange = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if nodecfg.Roaming != "off" {
|
||||
if nodecfg.IsLocal != "yes" {
|
||||
log.Println("Checking to see if public addresses have changed")
|
||||
extIP, err := getPublicIP()
|
||||
if err != nil {
|
||||
log.Println("Error encountered checking ip addresses: %v", err)
|
||||
}
|
||||
if nodecfg.Endpoint != extIP && extIP != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
nodecfg.Endpoint + " to " + extIP)
|
||||
log.Println("Updating address")
|
||||
nodecfg.Endpoint = extIP
|
||||
nodecfg.PostChanges = "true"
|
||||
node.Endpoint = extIP
|
||||
node.Postchanges = "true"
|
||||
ipchange = true
|
||||
}
|
||||
intIP, err := getPrivateAddr()
|
||||
if err != nil {
|
||||
log.Println("Error encountered checking ip addresses: %v", err)
|
||||
}
|
||||
if nodecfg.LocalAddress != intIP && intIP != "" {
|
||||
log.Println("Local Address has changed from " +
|
||||
nodecfg.LocalAddress + " to " + intIP)
|
||||
log.Println("Updating address")
|
||||
nodecfg.LocalAddress = intIP
|
||||
nodecfg.PostChanges = "true"
|
||||
node.Localaddress = intIP
|
||||
node.Postchanges = "true"
|
||||
ipchange = true
|
||||
}
|
||||
} else {
|
||||
log.Println("Checking to see if local addresses have changed")
|
||||
localIP, err := getLocalIP(nodecfg.LocalRange)
|
||||
if err != nil {
|
||||
log.Println("Error encountered checking ip addresses: %v", err)
|
||||
}
|
||||
if nodecfg.Endpoint != localIP && localIP != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
nodecfg.Endpoint + " to " + localIP)
|
||||
log.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" {
|
||||
log.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, false)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
node = server.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
err = config.ModConfig(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodecfg = cfg.Node
|
||||
}
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if servercfg.GRPCSSL == "on" {
|
||||
log.Println("using SSL")
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
} else {
|
||||
log.Println("using insecure GRPC connection")
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server: %v", err)
|
||||
return err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx := context.Background()
|
||||
log.Println("Authenticating with GRPC Server")
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Println("Authenticated")
|
||||
log.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 {
|
||||
log.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
|
||||
return nil
|
||||
}
|
||||
log.Println("Unable to process Check In request: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Println("Checked in.")
|
||||
if checkinres.Checkinresponse.Ispending {
|
||||
log.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 {
|
||||
log.Println("Error: %v", err)
|
||||
} else {
|
||||
currentiface := readres.Node.Interface
|
||||
ifaceupdate := newinterface != currentiface
|
||||
if err != nil {
|
||||
log.Println("Error retrieving interface: %v", err)
|
||||
}
|
||||
if ifaceupdate {
|
||||
log.Println("Interface update: " + currentiface +
|
||||
" >>>> " + newinterface)
|
||||
err := DeleteInterface(currentiface, nodecfg.PostDown)
|
||||
if err != nil {
|
||||
log.Println("ERROR DELETING INTERFACE: " + currentiface)
|
||||
}
|
||||
err = wireguard.SetWGConfig(network, false)
|
||||
if err != nil {
|
||||
log.Println("Error updating interface: %v", err)
|
||||
}
|
||||
log.Println("Error:", err)
|
||||
return false
|
||||
}
|
||||
err = wireguard.SetWGConfig(network, false)
|
||||
if err != nil {
|
||||
log.Println("Error:", err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return ipchange && err == nil
|
||||
}
|
||||
|
||||
if checkinres.Checkinresponse.Needconfigupdate {
|
||||
log.Println("Server has requested that node update config.")
|
||||
log.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, false)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
setupcheck = false
|
||||
} else if nodecfg.PostChanges == "true" {
|
||||
log.Println("Node has requested to update remote config.")
|
||||
log.Println("Posting local config to remote server.")
|
||||
postnode := server.GetNode(network)
|
||||
log.Println("POSTING NODE: ",postnode.Macaddress,postnode.Saveconfig)
|
||||
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)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
setupcheck = false
|
||||
func setDNS(node *models.Node, servercfg config.ServerConfig, nodecfg *models.Node) {
|
||||
if nodecfg.DNSOn == "yes" {
|
||||
log.Println("setting dns")
|
||||
ifacename := node.Interface
|
||||
nameserver := servercfg.CoreDNSAddr
|
||||
network := node.Network
|
||||
_ = local.UpdateDNS(ifacename, network, nameserver)
|
||||
}
|
||||
if checkinres.Checkinresponse.Needkeyupdate {
|
||||
log.Println("Server has requested that node update key pairs.")
|
||||
log.Println("Proceeding to re-generate key pairs for Wiregard.")
|
||||
err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Unable to process reset keys request: %v", err)
|
||||
}
|
||||
setupcheck = false
|
||||
}
|
||||
if checkinres.Checkinresponse.Needpeerupdate {
|
||||
log.Println("Server has requested that node update peer list.")
|
||||
log.Println("Updating peer list from remote server.")
|
||||
err = wireguard.SetWGConfig(network, true)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Unable to process Set Peers request: %v", err)
|
||||
}
|
||||
setupcheck = false
|
||||
}
|
||||
if checkinres.Checkinresponse.Needdelete {
|
||||
log.Println("This machine got the delete signal. Deleting.")
|
||||
err := LeaveNetwork(network)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
func checkNodeActions(node *models.Node, network string, servercfg config.ServerConfig) string {
|
||||
if node.Action == models.NODE_UPDATE_KEY {
|
||||
err := wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
|
||||
if err != nil {
|
||||
log.Println("Unable to process reset keys request:", err)
|
||||
return ""
|
||||
}
|
||||
node.Action = ""
|
||||
return ""
|
||||
}
|
||||
if setupcheck {
|
||||
iface := nodecfg.Interface
|
||||
_, err := net.InterfaceByName(iface)
|
||||
if err != nil {
|
||||
log.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
|
||||
err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
if node.Action == models.NODE_DELETE {
|
||||
err := LeaveNetwork(network)
|
||||
if err != nil {
|
||||
log.Println("Error:", err)
|
||||
return ""
|
||||
}
|
||||
return models.NODE_DELETE
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull changes if any (interface refresh)
|
||||
* - Save it
|
||||
* Check local changes for (ipAddress, publickey, configfile changes) (interface refresh)
|
||||
* - Save it
|
||||
* - Push it
|
||||
* Pull Peers (sync)
|
||||
*/
|
||||
func CheckConfig(cliconf config.ClientConfig) error {
|
||||
|
||||
network := cliconf.Network
|
||||
// node := server.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// nodecfg := cfg.Node
|
||||
servercfg := cfg.Server
|
||||
|
||||
newNode, err := Pull(network, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newNode.IsPending == "yes" {
|
||||
return errors.New("node is pending")
|
||||
}
|
||||
// check for interface change
|
||||
if cfg.Node.Interface != newNode.Interface {
|
||||
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
|
||||
log.Println("could not delete old interface", cfg.Node.Interface)
|
||||
}
|
||||
}
|
||||
|
||||
actionCompleted := checkNodeActions(newNode, network, servercfg)
|
||||
if actionCompleted == models.NODE_DELETE {
|
||||
return errors.New("node has been removed")
|
||||
}
|
||||
// Check if ip changed and push if so
|
||||
if checkIP(newNode, servercfg, cliconf, network) {
|
||||
err = Push(network)
|
||||
}
|
||||
//err = Pull(network)
|
||||
return err
|
||||
}
|
||||
|
||||
func Pull (network string) error{
|
||||
node := server.GetNode(network)
|
||||
/**
|
||||
* Pull the latest node from server
|
||||
* Perform action if necessary
|
||||
*/
|
||||
func Pull(network string, manual bool) (*models.Node, error) {
|
||||
node := config.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
var header metadata.MD
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
var header metadata.MD
|
||||
|
||||
if cfg.Node.IPForwarding == "yes" {
|
||||
if err = local.SetIPForwarding(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server:", err)
|
||||
return nil, err
|
||||
}
|
||||
wcclient := nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &nodepb.Object{
|
||||
Data: node.MacAddress + "###" + node.Network,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
}
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var resNode models.Node
|
||||
if err = json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resNode.PullChanges == "yes" || manual {
|
||||
if err = config.ModConfig(&resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = wireguard.SetWGConfig(network, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resNode.PullChanges = "no"
|
||||
nodeData, err := json.Marshal(&resNode)
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
Metadata: "",
|
||||
}
|
||||
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return &resNode, err
|
||||
}
|
||||
}
|
||||
setDNS(&node, servercfg, &cfg.Node)
|
||||
|
||||
return &node, err
|
||||
}
|
||||
|
||||
func Push(network string) error {
|
||||
postnode := config.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
var header metadata.MD
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server: %v", err)
|
||||
return err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server:", err)
|
||||
return err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
req := &nodepb.ReadNodeReq{
|
||||
Macaddress: node.Macaddress,
|
||||
Network: node.Nodenetwork,
|
||||
}
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = config.ModConfig(readres.Node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = wireguard.SetWGConfig(network, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate:", err)
|
||||
return err
|
||||
}
|
||||
nodeData, err := json.Marshal(&postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
Metadata: "",
|
||||
}
|
||||
data, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal([]byte(data.Data), &postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = config.ModConfig(&postnode)
|
||||
return err
|
||||
}
|
||||
|
||||
func Push (network string) error{
|
||||
postnode := server.GetNode(network)
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
var header metadata.MD
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server: %v", err)
|
||||
return err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
req := &nodepb.UpdateNodeReq{
|
||||
Node: &postnode,
|
||||
}
|
||||
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
return err
|
||||
}
|
||||
|
@@ -1,66 +1,68 @@
|
||||
package functions
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/credentials"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"context"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"strings"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/metadata"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
var (
|
||||
wcclient nodepb.NodeServiceClient
|
||||
wcclient nodepb.NodeServiceClient
|
||||
)
|
||||
|
||||
func ListPorts() error{
|
||||
func ListPorts() error {
|
||||
wgclient, err := wgctrl.New()
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
devices, err := wgclient.Devices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Here are your ports:")
|
||||
for _, i := range devices {
|
||||
for _, i := range devices {
|
||||
fmt.Println(i.ListenPort)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetFreePort(rangestart int32) (int32, error){
|
||||
wgclient, err := wgctrl.New()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
devices, err := wgclient.Devices()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
func GetFreePort(rangestart int32) (int32, error) {
|
||||
wgclient, err := wgctrl.New()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
devices, err := wgclient.Devices()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var portno int32
|
||||
portno = 0
|
||||
for x := rangestart; x <= 60000; x++ {
|
||||
for x := rangestart; x <= 60000; x++ {
|
||||
conflict := false
|
||||
for _, i := range devices {
|
||||
if int32(i.ListenPort) == x {
|
||||
conflict = true
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
if conflict {
|
||||
@@ -69,49 +71,49 @@ func GetFreePort(rangestart int32) (int32, error){
|
||||
portno = x
|
||||
break
|
||||
}
|
||||
return portno, err
|
||||
return portno, err
|
||||
}
|
||||
|
||||
func getLocalIP(localrange string) (string, error) {
|
||||
_, localRange, err := net.ParseCIDR(localrange)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
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()
|
||||
found = localRange.Contains(ip)
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
found = localRange.Contains(ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ifaces, err := net.Interfaces()
|
||||
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()
|
||||
found = localRange.Contains(ip)
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
found = localRange.Contains(ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found || local == "" {
|
||||
return "", errors.New("Failed to find local IP in range " + localrange)
|
||||
}
|
||||
@@ -120,10 +122,10 @@ func getLocalIP(localrange string) (string, error) {
|
||||
|
||||
func getPublicIP() (string, error) {
|
||||
|
||||
iplist := []string{"http://ip.client.gravitl.com","https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
iplist := []string{"http://ip.client.gravitl.com", "https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
endpoint := ""
|
||||
var err error
|
||||
for _, ipserver := range iplist {
|
||||
for _, ipserver := range iplist {
|
||||
resp, err := http.Get(ipserver)
|
||||
if err != nil {
|
||||
continue
|
||||
@@ -140,125 +142,97 @@ func getPublicIP() (string, error) {
|
||||
|
||||
}
|
||||
if err == nil && endpoint == "" {
|
||||
err = errors.New("Public Address Not Found.")
|
||||
err = errors.New("Public Address Not Found.")
|
||||
}
|
||||
return endpoint, err
|
||||
}
|
||||
|
||||
func getMacAddr() ([]string, error) {
|
||||
ifas, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var as []string
|
||||
for _, ifa := range ifas {
|
||||
a := ifa.HardwareAddr.String()
|
||||
if a != "" {
|
||||
as = append(as, a)
|
||||
}
|
||||
}
|
||||
return as, nil
|
||||
ifas, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var as []string
|
||||
for _, ifa := range ifas {
|
||||
a := ifa.HardwareAddr.String()
|
||||
if a != "" {
|
||||
as = append(as, a)
|
||||
}
|
||||
}
|
||||
return as, nil
|
||||
}
|
||||
|
||||
func getPrivateAddr() (string, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
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()
|
||||
found = true
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
err := errors.New("Local Address Not Found.")
|
||||
ifaces, err := net.Interfaces()
|
||||
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
|
||||
}
|
||||
return local, err
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
found = true
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if !found {
|
||||
ip = v.IP
|
||||
local = ip.String()
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
err := errors.New("Local Address Not Found.")
|
||||
return "", err
|
||||
}
|
||||
return local, err
|
||||
}
|
||||
|
||||
func needInterfaceUpdate(ctx context.Context, mac string, network string, iface string) (bool, string, error) {
|
||||
var header metadata.MD
|
||||
req := &nodepb.ReadNodeReq{
|
||||
Macaddress: mac,
|
||||
Network: network,
|
||||
}
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
oldiface := readres.Node.Interface
|
||||
var header metadata.MD
|
||||
req := &nodepb.Object{
|
||||
Data: mac + "###" + network,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
}
|
||||
readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
var resNode models.Node
|
||||
if err := json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
|
||||
return false, iface, err
|
||||
}
|
||||
oldiface := resNode.Interface
|
||||
|
||||
return iface != oldiface, oldiface, err
|
||||
return iface != oldiface, oldiface, err
|
||||
}
|
||||
|
||||
func GetNode(network string) nodepb.Node {
|
||||
func GetNode(network string) models.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 = true
|
||||
} else {
|
||||
node.Dnsoff = false
|
||||
}
|
||||
if nodecfg.IsDualStack == "yes" {
|
||||
node.Isdualstack = true
|
||||
} else {
|
||||
node.Isdualstack = false
|
||||
modcfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Error: %v", err)
|
||||
}
|
||||
if nodecfg.IsIngressGateway == "yes" {
|
||||
node.Isingressgateway = true
|
||||
} else {
|
||||
node.Isingressgateway = false
|
||||
}
|
||||
return node
|
||||
|
||||
return modcfg.Node
|
||||
}
|
||||
|
||||
func Uninstall() error {
|
||||
@@ -270,7 +244,7 @@ func Uninstall() error {
|
||||
for _, network := range networks {
|
||||
err = LeaveNetwork(network)
|
||||
if err != nil {
|
||||
log.Println("Encounter issue leaving network " + network + ": ", err)
|
||||
log.Println("Encounter issue leaving network "+network+": ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,40 +252,40 @@ func Uninstall() error {
|
||||
}
|
||||
|
||||
func LeaveNetwork(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
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
//need to implement checkin on server side
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Printf("Unable to establish client connection to " + servercfg.GRPCAddress + ": %v", err)
|
||||
}else {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
node := cfg.Node
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||
} else {
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Printf("Failed to authenticate: %v", err)
|
||||
log.Printf("Failed to authenticate: %v", err)
|
||||
} else {
|
||||
var header metadata.MD
|
||||
_, err = wcclient.DeleteNode(
|
||||
ctx,
|
||||
&nodepb.DeleteNodeReq{
|
||||
Macaddress: node.MacAddress,
|
||||
NetworkName: node.Network,
|
||||
},
|
||||
grpc.Header(&header),
|
||||
ctx,
|
||||
&nodepb.Object{
|
||||
Data: node.ID,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
},
|
||||
grpc.Header(&header),
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Encountered error deleting node: %v", err)
|
||||
@@ -323,41 +297,40 @@ func LeaveNetwork(network string) error {
|
||||
}
|
||||
err = local.WipeLocal(network)
|
||||
if err != nil {
|
||||
log.Printf("Unable to wipe local config: %v", err)
|
||||
log.Printf("Unable to wipe local config: %v", err)
|
||||
} else {
|
||||
log.Println("Removed " + node.Network + " network locally")
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
err = local.RemoveSystemDServices(network)
|
||||
err = local.RemoveSystemDServices(network)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DeleteInterface(ifacename string, postdown string) error{
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
func DeleteInterface(ifacename string, postdown string) error {
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
|
||||
cmdIPLinkDel := &exec.Cmd {
|
||||
Path: ipExec,
|
||||
Args: []string{ ipExec, "link", "del", ifacename },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
err = cmdIPLinkDel.Run()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if postdown != "" {
|
||||
runcmds := strings.Split(postdown, "; ")
|
||||
err = local.RunCmds(runcmds)
|
||||
if err != nil {
|
||||
log.Println("Error encountered running PostDown: " + err.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
cmdIPLinkDel := &exec.Cmd{
|
||||
Path: ipExec,
|
||||
Args: []string{ipExec, "link", "del", ifacename},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
err = cmdIPLinkDel.Run()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if postdown != "" {
|
||||
runcmds := strings.Split(postdown, "; ")
|
||||
err = local.RunCmds(runcmds)
|
||||
if err != nil {
|
||||
log.Println("Error encountered running PostDown: " + err.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func List() error{
|
||||
func List() error {
|
||||
|
||||
networks, err := GetNetworks()
|
||||
if err != nil {
|
||||
@@ -366,36 +339,34 @@ func List() error{
|
||||
for _, network := range networks {
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err == nil {
|
||||
//cfg2 := *cfg
|
||||
listconfig := &config.ListConfig{
|
||||
Name: cfg.Node.Name,
|
||||
Interface: cfg.Node.Interface,
|
||||
PrivateIPv4: cfg.Node.WGAddress,
|
||||
PrivateIPv6: cfg.Node.WGAddress6,
|
||||
PublicEndpoint: cfg.Node.Endpoint,
|
||||
}
|
||||
jsoncfg, _ := json.Marshal(listconfig)
|
||||
jsoncfg, _ := json.Marshal(
|
||||
map[string]string{
|
||||
"Name": cfg.Node.Name,
|
||||
"Interface": cfg.Node.Interface,
|
||||
"PrivateIPv4": cfg.Node.Address,
|
||||
"PrivateIPv6": cfg.Node.Address6,
|
||||
"PublicEndpoint": cfg.Node.Endpoint,
|
||||
})
|
||||
log.Println(network + ": " + string(jsoncfg))
|
||||
} else {
|
||||
log.Println(network + ": Could not retrieve network configuration.")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func GetNetworks() ([]string, error) {
|
||||
var networks []string
|
||||
files, err := ioutil.ReadDir("/etc/netclient")
|
||||
if err != nil {
|
||||
return networks, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if strings.Contains(f.Name(), "netconfig-") && !strings.Contains(f.Name(), "global-001"){
|
||||
networkname := stringAfter(f.Name(), "netconfig-")
|
||||
networks = append(networks, networkname)
|
||||
}
|
||||
}
|
||||
var networks []string
|
||||
files, err := ioutil.ReadDir("/etc/netclient")
|
||||
if err != nil {
|
||||
return networks, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if strings.Contains(f.Name(), "netconfig-") && !strings.Contains(f.Name(), "global-001") {
|
||||
networkname := stringAfter(f.Name(), "netconfig-")
|
||||
networks = append(networks, networkname)
|
||||
}
|
||||
}
|
||||
return networks, err
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package functions
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -11,6 +12,8 @@ import (
|
||||
"time"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/server"
|
||||
@@ -22,7 +25,7 @@ import (
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
func JoinNetwork(cfg config.ClientConfig) error {
|
||||
func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
|
||||
hasnet := local.HasNetwork(cfg.Network)
|
||||
if hasnet {
|
||||
@@ -100,12 +103,12 @@ func JoinNetwork(cfg config.ClientConfig) error {
|
||||
}
|
||||
if cfg.Node.Password == "" {
|
||||
cfg.Node.Password = GenPass()
|
||||
auth.StoreSecret(cfg.Node.Password, cfg.Node.Network)
|
||||
}
|
||||
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.")
|
||||
@@ -115,13 +118,13 @@ func JoinNetwork(cfg config.ClientConfig) error {
|
||||
} else {
|
||||
cfg.Node.Endpoint = cfg.Node.Endpoint
|
||||
}
|
||||
if cfg.Node.PrivateKey == "" {
|
||||
privatekey, err := wgtypes.GeneratePrivateKey()
|
||||
if privateKey == "" {
|
||||
wgPrivatekey, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cfg.Node.PrivateKey = privatekey.String()
|
||||
cfg.Node.PublicKey = privatekey.PublicKey().String()
|
||||
privateKey = wgPrivatekey.String()
|
||||
cfg.Node.PublicKey = wgPrivatekey.PublicKey().String()
|
||||
}
|
||||
|
||||
if cfg.Node.MacAddress == "" {
|
||||
@@ -134,8 +137,8 @@ func JoinNetwork(cfg config.ClientConfig) error {
|
||||
cfg.Node.MacAddress = macs[0]
|
||||
}
|
||||
}
|
||||
if cfg.Node.Port == 0 {
|
||||
cfg.Node.Port, err = GetFreePort(51821)
|
||||
if cfg.Node.ListenPort == 0 {
|
||||
cfg.Node.ListenPort, err = GetFreePort(51821)
|
||||
if err != nil {
|
||||
fmt.Printf("Error retrieving port: %v", err)
|
||||
}
|
||||
@@ -155,59 +158,65 @@ func JoinNetwork(cfg config.ClientConfig) error {
|
||||
|
||||
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,
|
||||
Saveconfig: cfg.Node.SaveConfig,
|
||||
Udpholepunch: cfg.Node.UDPHolePunch,
|
||||
postnode := &models.Node{
|
||||
Password: cfg.Node.Password,
|
||||
MacAddress: cfg.Node.MacAddress,
|
||||
AccessKey: cfg.Server.AccessKey,
|
||||
Network: cfg.Network,
|
||||
ListenPort: cfg.Node.ListenPort,
|
||||
PostUp: cfg.Node.PostUp,
|
||||
PostDown: cfg.Node.PostDown,
|
||||
PersistentKeepalive: cfg.Node.PersistentKeepalive,
|
||||
LocalAddress: cfg.Node.LocalAddress,
|
||||
Interface: cfg.Node.Interface,
|
||||
PublicKey: cfg.Node.PublicKey,
|
||||
Name: cfg.Node.Name,
|
||||
Endpoint: cfg.Node.Endpoint,
|
||||
SaveConfig: cfg.Node.SaveConfig,
|
||||
UDPHolePunch: cfg.Node.UDPHolePunch,
|
||||
}
|
||||
err = config.ModConfig(postnode)
|
||||
if err = config.ModConfig(postnode); err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := json.Marshal(&postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := wcclient.CreateNode(
|
||||
context.TODO(),
|
||||
&nodepb.CreateNodeReq{
|
||||
Node: postnode,
|
||||
&nodepb.Object{
|
||||
Data: string(data),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("node created on remote server...updating configs")
|
||||
node := res.Node
|
||||
if err != nil {
|
||||
|
||||
nodeData := res.Data
|
||||
var node models.Node
|
||||
if err = json.Unmarshal([]byte(nodeData), &node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if node.Dnsoff == true {
|
||||
cfg.Node.DNS = "yes"
|
||||
if node.DNSOn == "yes" {
|
||||
cfg.Node.DNSOn = "yes"
|
||||
}
|
||||
if !(cfg.Node.IsLocal == "yes") && node.Islocal && node.Localrange != "" {
|
||||
node.Localaddress, err = getLocalIP(node.Localrange)
|
||||
if !(cfg.Node.IsLocal == "yes") && node.IsLocal == "yes" && node.LocalRange != "" {
|
||||
node.LocalAddress, err = getLocalIP(node.LocalRange)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node.Endpoint = node.Localaddress
|
||||
node.Endpoint = node.LocalAddress
|
||||
}
|
||||
err = config.ModConfig(node)
|
||||
err = config.ModConfig(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if node.Ispending {
|
||||
if node.IsPending == "yes" {
|
||||
fmt.Println("Node is marked as PENDING.")
|
||||
fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
|
||||
if cfg.Daemon != "off" {
|
||||
@@ -216,18 +225,18 @@ func JoinNetwork(cfg config.ClientConfig) error {
|
||||
}
|
||||
}
|
||||
log.Println("retrieving remote peers")
|
||||
peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, cfg.Network, cfg.Server.GRPCAddress, node.Isdualstack, node.Isingressgateway)
|
||||
peers, hasGateway, gateways, err := server.GetPeers(node.MacAddress, cfg.Network, cfg.Server.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
||||
|
||||
if err != nil {
|
||||
log.Println("failed to retrieve peers")
|
||||
return err
|
||||
}
|
||||
err = wireguard.StorePrivKey(cfg.Node.PrivateKey, cfg.Network)
|
||||
err = wireguard.StorePrivKey(privateKey, cfg.Network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("starting wireguard")
|
||||
err = wireguard.InitWireguard(node, cfg.Node.PrivateKey, peers, hasGateway, gateways)
|
||||
err = wireguard.InitWireguard(&node, privateKey, peers, hasGateway, gateways)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -4,56 +4,56 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
//"github.com/davecgh/go-spew/spew"
|
||||
"log"
|
||||
"os/exec"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func SetDNS(nameserver string) error {
|
||||
bytes, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resolvstring := string(bytes)
|
||||
// //check whether s contains substring text
|
||||
hasdns := strings.Contains(resolvstring, nameserver)
|
||||
if hasdns {
|
||||
return nil
|
||||
}
|
||||
resolv, err := os.OpenFile("/etc/resolv.conf",os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resolv.Close()
|
||||
_, err = resolv.WriteString("nameserver " + nameserver + "\n")
|
||||
bytes, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resolvstring := string(bytes)
|
||||
// //check whether s contains substring text
|
||||
hasdns := strings.Contains(resolvstring, nameserver)
|
||||
if hasdns {
|
||||
return nil
|
||||
}
|
||||
resolv, err := os.OpenFile("/etc/resolv.conf", os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resolv.Close()
|
||||
_, err = resolv.WriteString("nameserver " + nameserver + "\n")
|
||||
|
||||
return err
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func UpdateDNS(ifacename string, network string, nameserver string) error {
|
||||
_, err := exec.LookPath("resolvectl")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.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 {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = exec.Command("resolvectl", "default-route", ifacename, "false").Output()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = exec.Command("resolvectl", "dns", ifacename, nameserver).Output()
|
||||
if err!= nil {
|
||||
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
_, err := exec.LookPath("resolvectl")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl domain " + ifacename + " ~" + network)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl default-route " + ifacename + " false")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl dns " + ifacename + " " + nameserver)
|
||||
if err != nil {
|
||||
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@@ -1,82 +1,121 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
//"github.com/davecgh/go-spew/spew"
|
||||
//"github.com/davecgh/go-spew/spew"
|
||||
"errors"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"io"
|
||||
"runtime"
|
||||
"strings"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
)
|
||||
|
||||
func SetIPForwarding() error {
|
||||
os := runtime.GOOS
|
||||
var err error
|
||||
switch os {
|
||||
case "linux":
|
||||
err = SetIPForwardingLinux()
|
||||
default:
|
||||
err = errors.New("This OS is not supported")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func SetIPForwardingLinux() error {
|
||||
out, err := RunCmd("sysctl net.ipv4.ip_forward")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||
return err
|
||||
} else {
|
||||
s := strings.Fields(string(out))
|
||||
if s[2] != "1" {
|
||||
_, err = RunCmd("sysctl -w net.ipv4.ip_forward=1")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunCmd(command string) (string, error) {
|
||||
args := strings.Fields(command)
|
||||
out, err := exec.Command(args[0], args[1:]...).Output()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
func RunCmds(commands []string) error {
|
||||
var err error
|
||||
for _, command := range commands {
|
||||
args := strings.Fields(command)
|
||||
out, err := exec.Command(args[0], args[1:]...).Output()
|
||||
if string(out) != "" {
|
||||
var err error
|
||||
for _, command := range commands {
|
||||
args := strings.Fields(command)
|
||||
out, err := exec.Command(args[0], args[1:]...).Output()
|
||||
if string(out) != "" {
|
||||
log.Println(string(out))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func ConfigureSystemD(network string) error {
|
||||
/*
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
//binarypath := path + "/netclient"
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
binarypath := dir + "/netclient"
|
||||
|
||||
_, err = os.Stat("/etc/netclient")
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir("/etc/netclient", 744)
|
||||
} else if err != nil {
|
||||
log.Println("couldnt find or create /etc/netclient")
|
||||
return err
|
||||
}
|
||||
|
||||
if !FileExists("/usr/local/bin/netclient") {
|
||||
os.Symlink("/etc/netclient/netclient","/usr/local/bin/netclient")
|
||||
/*
|
||||
_, err = copy(binarypath, "/usr/local/bin/netclient")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
}
|
||||
if !FileExists("/etc/netclient/netclient") {
|
||||
_, err = copy(binarypath, "/etc/netclient/netclient")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
binarypath := dir + "/netclient"
|
||||
|
||||
_, err = os.Stat("/etc/netclient")
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir("/etc/netclient", 744)
|
||||
} else if err != nil {
|
||||
log.Println("couldnt find or create /etc/netclient")
|
||||
return err
|
||||
}
|
||||
|
||||
if !FileExists("/usr/local/bin/netclient") {
|
||||
os.Symlink("/etc/netclient/netclient", "/usr/local/bin/netclient")
|
||||
/*
|
||||
_, err = copy(binarypath, "/usr/local/bin/netclient")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
}
|
||||
if !FileExists("/etc/netclient/netclient") {
|
||||
_, err = copy(binarypath, "/etc/netclient/netclient")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
systemservice := `[Unit]
|
||||
Description=network check for remote peers and local config
|
||||
@@ -94,18 +133,18 @@ WantedBy=multi-user.target
|
||||
Description=Calls the Netmaker Mesh Client Service
|
||||
|
||||
`
|
||||
systemtimer = systemtimer + "Requires=netclient@"+network+".service"
|
||||
systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
|
||||
|
||||
systemtimer = systemtimer +
|
||||
`
|
||||
systemtimer = systemtimer +
|
||||
`
|
||||
|
||||
[Timer]
|
||||
|
||||
`
|
||||
systemtimer = systemtimer + "Unit=netclient@"+network+".service"
|
||||
systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
|
||||
|
||||
systemtimer = systemtimer +
|
||||
`
|
||||
systemtimer = systemtimer +
|
||||
`
|
||||
|
||||
OnCalendar=*:*:0/30
|
||||
|
||||
@@ -117,67 +156,41 @@ WantedBy=timers.target
|
||||
timerbytes := []byte(systemtimer)
|
||||
|
||||
if !FileExists("/etc/systemd/system/netclient@.service") {
|
||||
err = ioutil.WriteFile("/etc/systemd/system/netclient@.service", servicebytes, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile("/etc/systemd/system/netclient@.service", servicebytes, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !FileExists("/etc/systemd/system/netclient-"+network+".timer") {
|
||||
err = ioutil.WriteFile("/etc/systemd/system/netclient-"+network+".timer", timerbytes, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
if !FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
||||
err = ioutil.WriteFile("/etc/systemd/system/netclient-"+network+".timer", timerbytes, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
//sysExec, err := exec.LookPath("systemctl")
|
||||
|
||||
cmdSysEnableService := exec.Command("systemctl", "enable", "netclient@.service")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "enable", "netclient@.service" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}*/
|
||||
cmdSysDaemonReload := exec.Command("systemctl", "daemon-reload")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "daemon-reload"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}*/
|
||||
cmdSysEnableTimer := exec.Command("systemctl", "enable", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "enable", "netclient-"+network+".timer" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}*/
|
||||
cmdSysStartTimer := exec.Command("systemctl", "start", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "start", "netclient-"+network+".timer"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}*/
|
||||
|
||||
err = cmdSysEnableService.Run()
|
||||
if err != nil {
|
||||
log.Println("Error enabling netclient@.service. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysDaemonReload.Run()
|
||||
if err != nil {
|
||||
log.Println("Error reloading system daemons. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysEnableTimer.Run()
|
||||
if err != nil {
|
||||
log.Println("Error enabling netclient.timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysStartTimer.Run()
|
||||
if err != nil {
|
||||
log.Println("Error starting netclient-"+network+".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl enable netclient@.service")
|
||||
if err != nil {
|
||||
log.Println("Error enabling netclient@.service. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl daemon-reload")
|
||||
if err != nil {
|
||||
log.Println("Error reloading system daemons. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl enable netclient-" + network + ".timer")
|
||||
if err != nil {
|
||||
log.Println("Error enabling netclient.timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl start netclient-" + network + ".timer")
|
||||
if err != nil {
|
||||
log.Println("Error starting netclient-" + network + ".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -188,7 +201,7 @@ func isOnlyService(network string) (bool, error) {
|
||||
return isonly, err
|
||||
}
|
||||
count := len(files)
|
||||
if count == 0 {
|
||||
if count == 0 {
|
||||
isonly = true
|
||||
}
|
||||
return isonly, err
|
||||
@@ -196,78 +209,67 @@ func isOnlyService(network string) (bool, error) {
|
||||
}
|
||||
|
||||
func RemoveSystemDServices(network string) error {
|
||||
//sysExec, err := exec.LookPath("systemctl")
|
||||
|
||||
//sysExec, err := exec.LookPath("systemctl")
|
||||
|
||||
fullremove, err := isOnlyService(network)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
cmdSysDisableService := exec.Command("systemctl","disable","netclient@.service")
|
||||
cmdSysDaemonReload := exec.Command("systemctl","daemon-reload")
|
||||
cmdSysResetFailed := exec.Command("systemctl","reset-failed")
|
||||
cmdSysStopTimer := exec.Command("systemctl", "stop", "netclient-"+network+".timer")
|
||||
cmdSysDisableTimer := exec.Command("systemctl", "disable", "netclient-"+network+".timer")
|
||||
if err != nil {
|
||||
log.Println("Error stopping netclient@.service. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
if fullremove {
|
||||
err = cmdSysDisableService.Run()
|
||||
if err != nil {
|
||||
log.Println("Error disabling netclient@.service. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl disable netclient@.service")
|
||||
if err != nil {
|
||||
log.Println("Error disabling netclient@.service. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
_, err = RunCmd("systemctl daemon-reload")
|
||||
if err != nil {
|
||||
log.Println("Error stopping netclient-" + network + ".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl disable netclient-" + network + ".timer")
|
||||
if err != nil {
|
||||
log.Println("Error disabling netclient-" + network + ".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysStopTimer.Run()
|
||||
if err != nil {
|
||||
log.Println("Error stopping netclient-"+network+".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysDisableTimer.Run()
|
||||
if err != nil {
|
||||
log.Println("Error disabling netclient-"+network+".timer. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
if fullremove {
|
||||
if FileExists("/etc/systemd/system/netclient@.service") {
|
||||
err = os.Remove("/etc/systemd/system/netclient@.service")
|
||||
}
|
||||
}
|
||||
if FileExists("/etc/systemd/system/netclient-"+network+".timer") {
|
||||
err = os.Remove("/etc/systemd/system/netclient-"+network+".timer")
|
||||
if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
||||
err = os.Remove("/etc/systemd/system/netclient-" + network + ".timer")
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("Error removing file. Please investigate.")
|
||||
log.Println(err)
|
||||
log.Println("Error removing file. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl daemon-reload")
|
||||
if err != nil {
|
||||
log.Println("Error reloading system daemons. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = RunCmd("systemctl reset-failed")
|
||||
if err != nil {
|
||||
log.Println("Error reseting failed system services. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysDaemonReload.Run()
|
||||
if err != nil {
|
||||
log.Println("Error reloading system daemons. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
err = cmdSysResetFailed.Run()
|
||||
if err != nil {
|
||||
log.Println("Error reseting failed system services. Please investigate.")
|
||||
log.Println(err)
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func WipeLocal(network string) error{
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
ifacename := nodecfg.Interface
|
||||
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"
|
||||
//home, err := homedir.Dir()
|
||||
home := "/etc/netclient"
|
||||
if FileExists(home + "/netconfig-" + network) {
|
||||
_ = os.Remove(home + "/netconfig-" + network)
|
||||
_ = os.Remove(home + "/netconfig-" + network)
|
||||
}
|
||||
if FileExists(home + "/nettoken-" + network) {
|
||||
_ = os.Remove(home + "/nettoken-" + network)
|
||||
@@ -276,79 +278,79 @@ func WipeLocal(network string) error{
|
||||
_ = os.Remove(home + "/wgkey-" + network)
|
||||
}
|
||||
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
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 {
|
||||
log.Println(err)
|
||||
}
|
||||
if nodecfg.PostDown != "" {
|
||||
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
||||
err = RunCmds(runcmds)
|
||||
if err != nil {
|
||||
log.Println("Error encountered running PostDown: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
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 {
|
||||
log.Println(err)
|
||||
}
|
||||
if nodecfg.PostDown != "" {
|
||||
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
||||
err = RunCmds(runcmds)
|
||||
if err != nil {
|
||||
log.Println("Error encountered running PostDown: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func WipeGRPCClient() error{
|
||||
home := "/etc/netclient"
|
||||
_ = os.Remove(home + "/netconfig-global-001")
|
||||
func WipeGRPCClient() error {
|
||||
home := "/etc/netclient"
|
||||
_ = os.Remove(home + "/netconfig-global-001")
|
||||
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
|
||||
cmdIPLinkDel := &exec.Cmd {
|
||||
Path: ipExec,
|
||||
Args: []string{ ipExec, "link", "del", "grpc-wg-001" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
err = cmdIPLinkDel.Run()
|
||||
return err
|
||||
cmdIPLinkDel := &exec.Cmd{
|
||||
Path: ipExec,
|
||||
Args: []string{ipExec, "link", "del", "grpc-wg-001"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
err = cmdIPLinkDel.Run()
|
||||
return err
|
||||
}
|
||||
|
||||
func HasNetwork(network string) bool{
|
||||
func HasNetwork(network string) bool {
|
||||
|
||||
return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
||||
FileExists("/etc/netclient/netconfig-"+network)
|
||||
return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
||||
FileExists("/etc/netclient/netconfig-"+network)
|
||||
|
||||
}
|
||||
|
||||
func copy(src, dst string) (int64, error) {
|
||||
sourceFileStat, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sourceFileStat, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !sourceFileStat.Mode().IsRegular() {
|
||||
return 0, errors.New(src + " is not a regular file")
|
||||
}
|
||||
if !sourceFileStat.Mode().IsRegular() {
|
||||
return 0, errors.New(src + " is not a regular file")
|
||||
}
|
||||
|
||||
source, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer source.Close()
|
||||
source, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
destination, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer destination.Close()
|
||||
nBytes, err := io.Copy(destination, source)
|
||||
destination, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer destination.Close()
|
||||
nBytes, err := io.Copy(destination, source)
|
||||
err = os.Chmod(dst, 0755)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return nBytes, err
|
||||
return nBytes, err
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/command"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
@@ -202,33 +203,12 @@ func main() {
|
||||
}
|
||||
|
||||
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.GetCLIConfigRegister(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cfg.GRPCWireGuard == "off" {
|
||||
log.Println("Server is not using WireGuard to secure GRPC. Skipping.")
|
||||
return err
|
||||
}
|
||||
if cfg.Client.ServerPrivateAddress == "" {
|
||||
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)
|
||||
cfg, pvtKey, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -240,7 +220,7 @@ func main() {
|
||||
err = errors.New("No server address provided.")
|
||||
return err
|
||||
}
|
||||
err = command.Join(cfg)
|
||||
err = command.Join(cfg, pvtKey)
|
||||
return err
|
||||
},
|
||||
},
|
||||
@@ -251,7 +231,7 @@ func main() {
|
||||
// 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)
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -266,7 +246,7 @@ func main() {
|
||||
// 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)
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -281,7 +261,7 @@ func main() {
|
||||
// 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)
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -296,7 +276,7 @@ func main() {
|
||||
// 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)
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -311,7 +291,7 @@ func main() {
|
||||
// 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)
|
||||
cfg, _, err := config.GetCLIConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -356,8 +336,7 @@ func main() {
|
||||
}
|
||||
|
||||
// start our application
|
||||
getID := exec.Command("id", "-u")
|
||||
out, err := getID.Output()
|
||||
out, err := local.RunCmd("id -u")
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@@ -1,373 +1,354 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/credentials"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"strconv"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
"io"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"google.golang.org/grpc"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/metadata"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
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
|
||||
node.Saveconfig = nodecfg.SaveConfig
|
||||
node.Udpholepunch = nodecfg.UDPHolePunch
|
||||
if nodecfg.DNS == "on" {
|
||||
node.Dnsoff = false
|
||||
} else {
|
||||
node.Dnsoff = true
|
||||
func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
|
||||
servercfg := cfg.Server
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
// == GRPC SETUP ==
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
if nodecfg.IsDualStack == "yes" {
|
||||
node.Isdualstack = true
|
||||
} else {
|
||||
node.Isdualstack = false
|
||||
}
|
||||
if nodecfg.IsIngressGateway == "yes" {
|
||||
node.Isingressgateway= true
|
||||
} else {
|
||||
node.Isingressgateway = false
|
||||
}
|
||||
return node
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
return wcclient, nil
|
||||
}
|
||||
|
||||
|
||||
func CheckIn(network string) (*models.Node, error) {
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node := cfg.Node
|
||||
wcclient, err := getGrpcClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// == run client action ==
|
||||
var header metadata.MD
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
nodeData, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := wcclient.ReadNode(
|
||||
ctx,
|
||||
&nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
},
|
||||
grpc.Header(&header),
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Encountered error checking in node: %v", err)
|
||||
}
|
||||
if err = json.Unmarshal([]byte(response.GetData()), &node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &node, err
|
||||
}
|
||||
|
||||
func RemoveNetwork(network string) error {
|
||||
//need to implement checkin on server side
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//need to implement checkin on server side
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
node := cfg.Node
|
||||
node := cfg.Node
|
||||
fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
var requestOpts grpc.DialOption
|
||||
requestOpts = grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
|
||||
if err != nil {
|
||||
log.Printf("Unable to establish client connection to " + servercfg.GRPCAddress + ": %v", err)
|
||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||
//return err
|
||||
}else {
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
} else {
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
//return err
|
||||
log.Printf("Failed to authenticate: %v", err)
|
||||
} else {
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
//return err
|
||||
log.Printf("Failed to authenticate: %v", err)
|
||||
} else {
|
||||
var header metadata.MD
|
||||
|
||||
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 = wcclient.DeleteNode(
|
||||
ctx,
|
||||
&nodepb.Object{
|
||||
Data: node.MacAddress + "###" + node.Network,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
},
|
||||
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)
|
||||
log.Printf("Unable to wipe local config: %v", err)
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
err = local.RemoveSystemDServices(network)
|
||||
err = local.RemoveSystemDServices(network)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
//need to implement checkin on server side
|
||||
hasGateway := false
|
||||
var gateways []string
|
||||
var peers []wgtypes.PeerConfig
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Issue retrieving config for network: " + network + ". Please investigate: %v", err)
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
keepalive := nodecfg.KeepAlive
|
||||
keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
|
||||
keepaliveserver, err := time.ParseDuration(strconv.FormatInt(int64(5), 10) + "s")
|
||||
if err != nil {
|
||||
log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
|
||||
}
|
||||
//need to implement checkin on server side
|
||||
hasGateway := false
|
||||
var gateways []string
|
||||
var peers []wgtypes.PeerConfig
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Issue retrieving config for network: "+network+". Please investigate: %v", err)
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
keepalive := nodecfg.PersistentKeepalive
|
||||
keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
|
||||
keepaliveserver, err := time.ParseDuration(strconv.FormatInt(int64(5), 10) + "s")
|
||||
if err != nil {
|
||||
log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
|
||||
}
|
||||
|
||||
|
||||
requestOpts := grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
requestOpts := grpc.WithInsecure()
|
||||
if cfg.Server.GRPCSSL == "on" {
|
||||
h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
|
||||
requestOpts = grpc.WithTransportCredentials(h2creds)
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(server, requestOpts)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||
}
|
||||
// Instantiate the BlogServiceClient with our client connection to the server
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||
}
|
||||
// Instantiate the BlogServiceClient with our client connection to the server
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
req := &nodepb.GetPeersReq{
|
||||
Macaddress: macaddress,
|
||||
Network: network,
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate.")
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
var header metadata.MD
|
||||
req := &nodepb.Object{
|
||||
Data: macaddress + "###" + network,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate.")
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
var header metadata.MD
|
||||
|
||||
stream, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
log.Println("Error retrieving peers")
|
||||
log.Println(err)
|
||||
return nil, hasGateway, gateways, err
|
||||
}
|
||||
for {
|
||||
res, err := stream.Recv()
|
||||
// If end of stream, break the loop
|
||||
response, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
log.Println("Error retrieving peers")
|
||||
log.Println(err)
|
||||
return nil, hasGateway, gateways, err
|
||||
}
|
||||
var nodes []models.Node
|
||||
if err := json.Unmarshal([]byte(response.GetData()), &nodes); err != nil {
|
||||
log.Println("Error unmarshaling data for peers")
|
||||
return nil, hasGateway, gateways, err
|
||||
}
|
||||
for _, node := range nodes {
|
||||
pubkey, err := wgtypes.ParseKey(node.PublicKey)
|
||||
if err != nil {
|
||||
fmt.Println("error parsing key")
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
// if err, return an error
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "mongo: no documents in result") {
|
||||
continue
|
||||
} else {
|
||||
fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
|
||||
fmt.Println(res)
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
}
|
||||
pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
|
||||
if err != nil {
|
||||
fmt.Println("error parsing key")
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
|
||||
if nodecfg.PublicKey == res.Peers.Publickey {
|
||||
continue
|
||||
}
|
||||
if nodecfg.Endpoint == res.Peers.Endpoint {
|
||||
if nodecfg.LocalAddress != res.Peers.Localaddress && res.Peers.Localaddress != "" {
|
||||
res.Peers.Endpoint = res.Peers.Localaddress
|
||||
if nodecfg.PublicKey == node.PublicKey {
|
||||
continue
|
||||
}
|
||||
if nodecfg.Endpoint == node.Endpoint {
|
||||
if nodecfg.LocalAddress != node.LocalAddress && node.LocalAddress != "" {
|
||||
node.Endpoint = node.LocalAddress
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var peer wgtypes.PeerConfig
|
||||
var peeraddr = net.IPNet{
|
||||
IP: net.ParseIP(res.Peers.Address),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
var allowedips []net.IPNet
|
||||
allowedips = append(allowedips, peeraddr)
|
||||
if res.Peers.Isegressgateway {
|
||||
hasGateway = true
|
||||
ranges := strings.Split(res.Peers.Egressgatewayranges, ",")
|
||||
var peer wgtypes.PeerConfig
|
||||
var peeraddr = net.IPNet{
|
||||
IP: net.ParseIP(node.Address),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
var allowedips []net.IPNet
|
||||
allowedips = append(allowedips, peeraddr)
|
||||
if node.IsEgressGateway == "yes" {
|
||||
hasGateway = true
|
||||
ranges := node.EgressGatewayRanges
|
||||
for _, iprange := range ranges {
|
||||
gateways = append(gateways,iprange)
|
||||
_, ipnet, err := net.ParseCIDR(iprange)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR ENCOUNTERED SETTING GATEWAY")
|
||||
fmt.Println("NOT SETTING GATEWAY")
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(" Gateway Range: " + iprange)
|
||||
allowedips = append(allowedips, *ipnet)
|
||||
}
|
||||
gateways = append(gateways, iprange)
|
||||
_, ipnet, err := net.ParseCIDR(iprange)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR ENCOUNTERED SETTING GATEWAY")
|
||||
fmt.Println("NOT SETTING GATEWAY")
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(" Gateway Range: " + iprange)
|
||||
allowedips = append(allowedips, *ipnet)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Address6 != "" && dualstack {
|
||||
var addr6 = net.IPNet{
|
||||
IP: net.ParseIP(node.Address6),
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
}
|
||||
allowedips = append(allowedips, addr6)
|
||||
}
|
||||
if nodecfg.Name == "netmaker" {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
PersistentKeepaliveInterval: &keepaliveserver,
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
}
|
||||
if res.Peers.Address6 != "" && dualstack {
|
||||
var addr6 = net.IPNet{
|
||||
IP: net.ParseIP(res.Peers.Address6),
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
}
|
||||
allowedips = append(allowedips, addr6)
|
||||
}
|
||||
if nodecfg.Name == "netmaker" {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
PersistentKeepaliveInterval: &keepaliveserver,
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
} else if keepalive != 0 {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
PersistentKeepaliveInterval: &keepalivedur,
|
||||
Endpoint: &net.UDPAddr{
|
||||
IP: net.ParseIP(res.Peers.Endpoint),
|
||||
Port: int(res.Peers.Listenport),
|
||||
},
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
} else {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
Endpoint: &net.UDPAddr{
|
||||
IP: net.ParseIP(res.Peers.Endpoint),
|
||||
Port: int(res.Peers.Listenport),
|
||||
},
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
}
|
||||
peers = append(peers, peer)
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
PersistentKeepaliveInterval: &keepalivedur,
|
||||
Endpoint: &net.UDPAddr{
|
||||
IP: net.ParseIP(node.Endpoint),
|
||||
Port: int(node.ListenPort),
|
||||
},
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
} else {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
Endpoint: &net.UDPAddr{
|
||||
IP: net.ParseIP(node.Endpoint),
|
||||
Port: int(node.ListenPort),
|
||||
},
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
}
|
||||
peers = append(peers, peer)
|
||||
|
||||
}
|
||||
if isIngressGateway {
|
||||
extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
|
||||
if err == nil {
|
||||
peers = append(peers, extPeers...)
|
||||
} else {
|
||||
fmt.Println("ERROR RETRIEVING EXTERNAL PEERS")
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
if isIngressGateway {
|
||||
extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
|
||||
if err == nil {
|
||||
peers = append(peers, extPeers...)
|
||||
} else {
|
||||
fmt.Println("ERROR RETRIEVING EXTERNAL PEERS")
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
return peers, hasGateway, gateways, err
|
||||
}
|
||||
|
||||
func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
|
||||
var peers []wgtypes.PeerConfig
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Issue retrieving config for network: " + network + ". Please investigate: %v", err)
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
var peers []wgtypes.PeerConfig
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
log.Fatalf("Issue retrieving config for network: "+network+". Please investigate: %v", err)
|
||||
}
|
||||
nodecfg := cfg.Node
|
||||
|
||||
requestOpts := grpc.WithInsecure()
|
||||
conn, err := grpc.Dial(server, requestOpts)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||
}
|
||||
// Instantiate the BlogServiceClient with our client connection to the server
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
requestOpts := grpc.WithInsecure()
|
||||
conn, err := grpc.Dial(server, requestOpts)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||
}
|
||||
// Instantiate the BlogServiceClient with our client connection to the server
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
req := &nodepb.GetExtPeersReq{
|
||||
Macaddress: macaddress,
|
||||
Network: network,
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to authenticate.")
|
||||
return peers, err
|
||||
}
|
||||
var header metadata.MD
|
||||
req := &nodepb.Object{
|
||||
Data: macaddress + "###" + network,
|
||||
Type: nodepb.STRING_TYPE,
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, err = auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to authenticate.")
|
||||
return peers, err
|
||||
}
|
||||
var header metadata.MD
|
||||
|
||||
stream, err := wcclient.GetExtPeers(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
fmt.Println("Error retrieving peers")
|
||||
fmt.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
for {
|
||||
res, err := stream.Recv()
|
||||
// If end of stream, break the loop
|
||||
responseObject, err := wcclient.GetExtPeers(ctx, req, grpc.Header(&header))
|
||||
if err != nil {
|
||||
fmt.Println("Error retrieving peers")
|
||||
fmt.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
var extPeers []models.Node
|
||||
if err = json.Unmarshal([]byte(responseObject.Data), extPeers); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, extPeer := range extPeers {
|
||||
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
|
||||
if err != nil {
|
||||
fmt.Println("error parsing key")
|
||||
return peers, err
|
||||
}
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
// if err, return an error
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "mongo: no documents in result") {
|
||||
continue
|
||||
} else {
|
||||
fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
|
||||
fmt.Println(res)
|
||||
return peers, err
|
||||
}
|
||||
}
|
||||
pubkey, err := wgtypes.ParseKey(res.Extpeers.Publickey)
|
||||
if err != nil {
|
||||
fmt.Println("error parsing key")
|
||||
return peers, err
|
||||
}
|
||||
if nodecfg.PublicKey == extPeer.PublicKey {
|
||||
continue
|
||||
}
|
||||
|
||||
if nodecfg.PublicKey == res.Extpeers.Publickey {
|
||||
continue
|
||||
}
|
||||
var peer wgtypes.PeerConfig
|
||||
var peeraddr = net.IPNet{
|
||||
IP: net.ParseIP(extPeer.Address),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
var allowedips []net.IPNet
|
||||
allowedips = append(allowedips, peeraddr)
|
||||
|
||||
var peer wgtypes.PeerConfig
|
||||
var peeraddr = net.IPNet{
|
||||
IP: net.ParseIP(res.Extpeers.Address),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
var allowedips []net.IPNet
|
||||
allowedips = append(allowedips, peeraddr)
|
||||
if extPeer.Address6 != "" && dualstack {
|
||||
var addr6 = net.IPNet{
|
||||
IP: net.ParseIP(extPeer.Address6),
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
}
|
||||
allowedips = append(allowedips, addr6)
|
||||
}
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
peers = append(peers, peer)
|
||||
|
||||
if res.Extpeers.Address6 != "" && dualstack {
|
||||
var addr6 = net.IPNet{
|
||||
IP: net.ParseIP(res.Extpeers.Address6),
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
}
|
||||
allowedips = append(allowedips, addr6)
|
||||
}
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedips,
|
||||
}
|
||||
peers = append(peers, peer)
|
||||
|
||||
}
|
||||
return peers, err
|
||||
}
|
||||
return peers, err
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package wireguard
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
@@ -53,12 +53,9 @@ func InitGRPCWireguard(client models.IntClient) error {
|
||||
if client.Address6 == "" && client.Address == "" {
|
||||
return errors.New("no address to configure")
|
||||
}
|
||||
cmdIPDevLinkAdd := exec.Command("ip", "link", "add", "dev", ifacename, "type", "wireguard")
|
||||
cmdIPAddrAdd := exec.Command("ip", "address", "add", "dev", ifacename, client.Address+"/24")
|
||||
cmdIPAddr6Add := exec.Command("ip", "address", "add", "dev", ifacename, client.Address6+"/64")
|
||||
currentiface, err := net.InterfaceByName(ifacename)
|
||||
if err != nil {
|
||||
err = cmdIPDevLinkAdd.Run()
|
||||
_, err = local.RunCmd("ip link add dev " + ifacename + " type wireguard")
|
||||
if err != nil && !strings.Contains(err.Error(), "exists") {
|
||||
log.Println("Error creating interface")
|
||||
}
|
||||
@@ -77,14 +74,14 @@ func InitGRPCWireguard(client models.IntClient) error {
|
||||
}
|
||||
}
|
||||
if !match && client.Address != "" {
|
||||
err = cmdIPAddrAdd.Run()
|
||||
_, err = local.RunCmd("ip address add dev " + ifacename + " " + client.Address + "/24")
|
||||
if err != nil {
|
||||
log.Println("Error adding ipv4 address")
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
if !match6 && client.Address6 != "" {
|
||||
err = cmdIPAddr6Add.Run()
|
||||
_, err = local.RunCmd("ip address add dev" + ifacename + " " + client.Address6 + "/64")
|
||||
if err != nil {
|
||||
log.Println("Error adding ipv6 address")
|
||||
fmt.Println(err)
|
||||
@@ -133,10 +130,8 @@ func InitGRPCWireguard(client models.IntClient) error {
|
||||
}
|
||||
}
|
||||
|
||||
cmdIPLinkUp := exec.Command("ip", "link", "set", "up", "dev", ifacename)
|
||||
cmdIPLinkDown := exec.Command("ip", "link", "set", "down", "dev", ifacename)
|
||||
err = cmdIPLinkDown.Run()
|
||||
err = cmdIPLinkUp.Run()
|
||||
_, err = local.RunCmd("ip link set up dev " + ifacename)
|
||||
_, err = local.RunCmd("ip link set down dev " + ifacename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -144,7 +139,7 @@ func InitGRPCWireguard(client models.IntClient) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
||||
func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
||||
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
if err != nil {
|
||||
@@ -159,7 +154,7 @@ func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
modcfg, err := config.ReadConfig(node.Nodenetwork)
|
||||
modcfg, err := config.ReadConfig(node.Network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -183,29 +178,16 @@ func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
||||
log.Fatal("no address to configure")
|
||||
}
|
||||
nameserver := servercfg.CoreDNSAddr
|
||||
network := node.Nodenetwork
|
||||
network := node.Network
|
||||
if nodecfg.Network != "" {
|
||||
network = nodecfg.Network
|
||||
} else if node.Nodenetwork != "" {
|
||||
network = node.Nodenetwork
|
||||
} else if node.Network != "" {
|
||||
network = node.Network
|
||||
}
|
||||
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,
|
||||
}
|
||||
cmdIPLinkDelete := exec.Command("ip", "link", "delete", "dev", ifacename)
|
||||
|
||||
delErr := cmdIPLinkDelete.Run()
|
||||
addLinkErr := cmdIPDevLinkAdd.Run()
|
||||
addErr := cmdIPAddrAdd.Run()
|
||||
_, delErr := local.RunCmd("ip link delete dev " + ifacename)
|
||||
_, addLinkErr := local.RunCmd(ipExec + " link add dev " + ifacename + " type wireguard")
|
||||
_, addErr := local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address + "/24")
|
||||
if delErr != nil {
|
||||
log.Println(delErr)
|
||||
}
|
||||
@@ -216,7 +198,7 @@ func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
||||
log.Println(addErr)
|
||||
}
|
||||
var nodeport int
|
||||
nodeport = int(node.Listenport)
|
||||
nodeport = int(node.ListenPort)
|
||||
|
||||
conf := wgtypes.Config{}
|
||||
if nodecfg.UDPHolePunch == "yes" && nodecfg.Name != "netmaker" {
|
||||
@@ -254,7 +236,7 @@ func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
||||
}
|
||||
}
|
||||
//=========DNS Setup==========\\
|
||||
if nodecfg.DNS == "on" {
|
||||
if nodecfg.DNSOn == "yes" {
|
||||
_ = local.UpdateDNS(ifacename, network, nameserver)
|
||||
}
|
||||
//=========End DNS Setup=======\\
|
||||
@@ -295,16 +277,16 @@ func InitWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
||||
}
|
||||
if hasGateway {
|
||||
for _, gateway := range gateways {
|
||||
out, err := exec.Command(ipExec, "-4", "route", "add", gateway, "dev", ifacename).Output()
|
||||
out, err := local.RunCmd(ipExec + " -4 route add " + gateway + " dev " + ifacename)
|
||||
fmt.Println(string(out))
|
||||
if err != nil {
|
||||
fmt.Println("Error encountered adding gateway: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Address6 != "" && node.Isdualstack {
|
||||
if node.Address6 != "" && node.IsDualStack == "yes" {
|
||||
fmt.Println("Adding address: " + node.Address6)
|
||||
out, err := exec.Command(ipExec, "address", "add", "dev", ifacename, node.Address6+"/64").Output()
|
||||
out, err := local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address6 + "/64")
|
||||
if err != nil {
|
||||
fmt.Println(out)
|
||||
fmt.Println("Error encountered adding ipv6: " + err.Error())
|
||||
@@ -345,7 +327,7 @@ func SetWGKeyConfig(network string, serveraddr string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
node := server.GetNode(network)
|
||||
node := config.GetNode(network)
|
||||
|
||||
privatekey, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
@@ -354,7 +336,7 @@ func SetWGKeyConfig(network string, serveraddr string) error {
|
||||
privkeystring := privatekey.String()
|
||||
publickey := privatekey.PublicKey()
|
||||
|
||||
node.Publickey = publickey.String()
|
||||
node.PublicKey = publickey.String()
|
||||
|
||||
err = StorePrivKey(privkeystring, network)
|
||||
if err != nil {
|
||||
@@ -365,10 +347,15 @@ func SetWGKeyConfig(network string, serveraddr string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
postnode := server.GetNode(network)
|
||||
postnode := config.GetNode(network)
|
||||
|
||||
req := &nodepb.UpdateNodeReq{
|
||||
Node: &postnode,
|
||||
nodeData, err := json.Marshal(&postnode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := &nodepb.Object{
|
||||
Data: string(nodeData),
|
||||
Type: nodepb.NODE_TYPE,
|
||||
}
|
||||
|
||||
_, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
|
||||
@@ -392,9 +379,9 @@ func SetWGConfig(network string, peerupdate bool) error {
|
||||
}
|
||||
servercfg := cfg.Server
|
||||
nodecfg := cfg.Node
|
||||
node := server.GetNode(network)
|
||||
node := config.GetNode(network)
|
||||
|
||||
peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, nodecfg.Network, servercfg.GRPCAddress, node.Isdualstack, node.Isingressgateway)
|
||||
peers, hasGateway, gateways, err := server.GetPeers(node.MacAddress, nodecfg.Network, servercfg.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -403,7 +390,7 @@ func SetWGConfig(network string, peerupdate bool) error {
|
||||
return err
|
||||
}
|
||||
if peerupdate {
|
||||
SetPeers(node.Interface, node.Keepalive, peers)
|
||||
SetPeers(node.Interface, node.PersistentKeepalive, peers)
|
||||
} else {
|
||||
err = InitWireguard(&node, privkey, peers, hasGateway, gateways)
|
||||
}
|
||||
@@ -426,29 +413,30 @@ func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) {
|
||||
return
|
||||
}
|
||||
for _, peer := range peers {
|
||||
|
||||
|
||||
for _, currentPeer := range device.Peers {
|
||||
if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
|
||||
currentPeer.PublicKey.String() == peer.PublicKey.String() {
|
||||
err := exec.Command("wg","set",iface,"peer",currentPeer.PublicKey.String(),"delete").Run()
|
||||
if err != nil {
|
||||
log.Println("error setting peer",peer.Endpoint.String(),)
|
||||
}
|
||||
if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
|
||||
currentPeer.PublicKey.String() == peer.PublicKey.String() {
|
||||
_, err := local.RunCmd("wg set " + iface + " peer " + currentPeer.PublicKey.String() + " delete")
|
||||
if err != nil {
|
||||
log.Println("error setting peer", peer.Endpoint.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
udpendpoint := peer.Endpoint.IP.String()+":"+peer.Endpoint.IP.String()
|
||||
}
|
||||
udpendpoint := peer.Endpoint.IP.String() + ":" + peer.Endpoint.IP.String()
|
||||
var allowedips string
|
||||
var iparr []string
|
||||
for _, ipaddr := range peer.AllowedIPs {
|
||||
iparr = append(iparr,ipaddr.String())
|
||||
iparr = append(iparr, ipaddr.String())
|
||||
}
|
||||
allowedips = strings.Join(iparr,",")
|
||||
err := exec.Command("wg","set",iface,"peer",peer.PublicKey.String(),
|
||||
"endpoint",udpendpoint,
|
||||
"persistent-keepalive",string(keepalive),
|
||||
"allowed-ips",allowedips)
|
||||
allowedips = strings.Join(iparr, ",")
|
||||
|
||||
_, err = local.RunCmd("wg set " + iface + " peer " + peer.PublicKey.String() +
|
||||
" endpoint " + udpendpoint +
|
||||
" persistent-keepalive " + string(keepalive) +
|
||||
" allowed-ips " + allowedips)
|
||||
if err != nil {
|
||||
log.Println("error setting peer",peer.Endpoint.String(),)
|
||||
log.Println("error setting peer", peer.Endpoint.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
@@ -121,7 +122,7 @@ func RemoveNetwork(network string) (bool, error) {
|
||||
log.Println("could not find /etc/netclient")
|
||||
return false, err
|
||||
}
|
||||
cmdoutput, err := exec.Command("/etc/netclient/netclient", "leave", "-n", network).Output()
|
||||
cmdoutput, err := local.RunCmd("/etc/netclient/netclient leave -n " + network)
|
||||
if err != nil {
|
||||
log.Println(string(cmdoutput))
|
||||
return false, err
|
||||
|
Reference in New Issue
Block a user