| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 | package serverimport (	"fmt"	"context"	"log"	"strings"	"strconv"	"net"	"time"	"io"        "golang.zx2c4.com/wireguard/wgctrl/wgtypes"	"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"	"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	if nodecfg.DNS == "on" {		node.Dnsoff = false	} else {		node.Dnsoff = true	}        if nodecfg.IsDualStack == "yes" {                node.Isdualstack = true        } else {                node.Isdualstack = false        }        if nodecfg.IsIngressGateway == "yes" {                node.Isingressgateway= true        } else {                node.Isingressgateway = false        }        return node}func RemoveNetwork(network string) error {        //need to  implement checkin on server side        cfg, err := config.ReadConfig(network)        if err != nil {                return err        }	servercfg := cfg.Server        node := cfg.Node	fmt.Println("Deleting remote node with MAC: " + node.MacAddress)        var wcclient nodepb.NodeServiceClient        var requestOpts grpc.DialOption        requestOpts = grpc.WithInsecure()        conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)	if err != nil {                log.Printf("Unable to establish client connection to " + servercfg.GRPCAddress + ": %v", err)		//return err        }else {        wcclient = nodepb.NewNodeServiceClient(conn)        ctx := context.Background()        fmt.Println("Authenticating with GRPC Server")        ctx, err = auth.SetJWT(wcclient, network)        if err != nil {                //return err                log.Printf("Failed to authenticate: %v", err)        } else {        fmt.Println("Authenticated")        var header metadata.MD        _, err = wcclient.DeleteNode(                ctx,                &nodepb.DeleteNodeReq{                        Macaddress: node.MacAddress,                        NetworkName: node.Network,                },                grpc.Header(&header),        )        if err != nil {		log.Printf("Encountered error deleting node: %v", err)		fmt.Println(err)        } else {		fmt.Println("Deleted node " + node.MacAddress)	}	}	}	err = local.WipeLocal(network)	if err != nil {                log.Printf("Unable to wipe local config: %v", err)	}	err =  local.RemoveSystemDServices(network)        if err != nil {                return err                log.Printf("Unable to remove systemd services: %v", err)        }	fmt.Printf("Please investigate any stated errors to ensure proper removal.")	fmt.Printf("Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator.")	return nil}func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {        //need to  implement checkin on server side        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")        if err != nil {                log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)        }        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.GetPeersReq{                Macaddress: macaddress,                Network: network,        }        ctx := context.Background()        ctx, err = auth.SetJWT(wcclient, network)        if err != nil {                fmt.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 {                fmt.Println("Error retrieving peers")                fmt.Println(err)                return nil, hasGateway, gateways, err        }        for {                res, err := stream.Recv()                // If end of stream, break the loop                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 {                        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                        gateways = append(gateways,res.Peers.Egressgatewayrange)                        _, ipnet, err := net.ParseCIDR(res.Peers.Egressgatewayrange)                        if err != nil {                                fmt.Println("ERROR ENCOUNTERED SETTING GATEWAY")                                fmt.Println("NOT SETTING GATEWAY")                                fmt.Println(err)                        } else {                                fmt.Println("    Gateway Range: "  + res.Peers.Egressgatewayrange)                                allowedips = append(allowedips, *ipnet)                        }                }                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 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)        }        if isIngressGateway {                extPeers, err := GetExtPeers(macaddress, network, server, dualstack)                if err == nil {                        peers = append(peers, extPeers...)                        fmt.Println("Added " + strconv.Itoa(len(extPeers)) + " external clients.")                } 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        fmt.Println("Registering with GRPC Server")        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        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                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 == res.Extpeers.Publickey {                        continue                }                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 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}
 |