mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-04 16:33:49 +08:00
began refactoring of client
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user