diff --git a/main.go b/main.go
index e5449f1a..39fb5ffc 100644
--- a/main.go
+++ b/main.go
@@ -17,7 +17,7 @@ import (
"github.com/gravitl/netmaker/functions"
nodepb "github.com/gravitl/netmaker/grpc"
"github.com/gravitl/netmaker/models"
- "github.com/gravitl/netmaker/netclient/local"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
"google.golang.org/grpc"
)
@@ -38,7 +38,7 @@ func initialize() { // Client Mode Prereq Check
}
log.Println("database successfully connected.")
if servercfg.IsClientMode() {
- output, err := local.RunCmd("id -u", true)
+ output, err := ncutils.RunCmd("id -u", true)
if err != nil {
log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
log.Fatal(output, err)
diff --git a/netclient/auth/auth.go b/netclient/auth/auth.go
index 2586a60b..d1841188 100644
--- a/netclient/auth/auth.go
+++ b/netclient/auth/auth.go
@@ -6,7 +6,7 @@ import (
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/config"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
// "os"
"context"
@@ -20,7 +20,7 @@ import (
// 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 := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
tokentext, err := ioutil.ReadFile(home + "nettoken-" + network)
if err != nil {
err = AutoLogin(client, network)
@@ -42,7 +42,7 @@ func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, e
}
func AutoLogin(client nodepb.NodeServiceClient, network string) error {
- home := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
cfg, err := config.ReadConfig(network)
if err != nil {
return err
@@ -79,12 +79,12 @@ func AutoLogin(client nodepb.NodeServiceClient, network string) error {
func StoreSecret(key string, network string) error {
d1 := []byte(key)
- err := ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
+ err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
return err
}
func RetrieveSecret(network string) (string, error) {
- dat, err := ioutil.ReadFile(netclientutils.GetNetclientPathSpecific() + "secret-" + network)
+ dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + network)
return string(dat), err
}
diff --git a/netclient/command/commands.go b/netclient/command/commands.go
index 965c5774..8c4631c8 100644
--- a/netclient/command/commands.go
+++ b/netclient/command/commands.go
@@ -8,9 +8,9 @@ import (
nodepb "github.com/gravitl/netmaker/grpc"
"github.com/gravitl/netmaker/netclient/config"
+ "github.com/gravitl/netmaker/netclient/daemon"
"github.com/gravitl/netmaker/netclient/functions"
- "github.com/gravitl/netmaker/netclient/local"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"golang.zx2c4.com/wireguard/wgctrl"
)
@@ -28,34 +28,30 @@ func Join(cfg config.ClientConfig, privateKey string) error {
if err != nil && !cfg.DebugJoin {
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
- log.Println("Error installing: ", err)
+ ncutils.PrintLog("error installing: "+err.Error(), 1)
err = functions.LeaveNetwork(cfg.Network)
if err != nil {
- err = local.WipeLocal(cfg.Network)
+ err = functions.WipeLocal(cfg.Network)
if err != nil {
- log.Println("Error removing artifacts: ", err)
+ ncutils.PrintLog("error removing artifacts: "+err.Error(), 1)
}
}
if cfg.Daemon != "off" {
- if netclientutils.IsLinux() {
- err = local.RemoveSystemDServices(cfg.Network)
+ if ncutils.IsLinux() {
+ err = daemon.RemoveSystemDServices(cfg.Network)
}
if err != nil {
- log.Println("Error removing services: ", err)
+ ncutils.PrintLog("error removing services: "+err.Error(), 1)
}
}
+ } else {
+ ncutils.PrintLog("success", 0)
}
return err
}
- log.Println("joined " + cfg.Network)
+ ncutils.PrintLog("joined "+cfg.Network, 1)
if cfg.Daemon != "off" {
- if netclientutils.IsWindows() {
- err = local.CreateAndRunWindowsDaemon()
- } else if netclientutils.IsMac() {
- err = local.CreateAndRunMacDaemon()
- } else {
- err = functions.InstallDaemon(cfg)
- }
+ err = daemon.InstallDaemon(cfg)
}
return err
}
@@ -75,13 +71,13 @@ func RunUserspaceDaemon() {
func CheckIn(cfg config.ClientConfig) error {
var err error
if cfg.Network == "" {
- log.Println("Required, '-n'. No network provided. Exiting.")
+ ncutils.PrintLog("required, '-n', exiting", 0)
os.Exit(1)
} else if cfg.Network == "all" {
- log.Println("Running CheckIn for all networks.")
+ ncutils.PrintLog("running checkin for all networks", 1)
networks, err := functions.GetNetworks()
if err != nil {
- log.Println("Error retrieving networks. Exiting.")
+ ncutils.PrintLog("error retrieving networks, exiting", 1)
return err
}
for _, network := range networks {
@@ -91,14 +87,14 @@ func CheckIn(cfg config.ClientConfig) error {
}
err = functions.CheckConfig(*currConf)
if err != nil {
- log.Printf("Error checking in for "+network+" network: ", err)
+ ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
} else {
- log.Println("checked in successfully for " + network)
+ ncutils.PrintLog("checked in successfully for "+network, 1)
}
}
if len(networks) == 0 {
- if netclientutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
- local.StopWindowsDaemon()
+ if ncutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
+ daemon.StopWindowsDaemon()
}
}
err = nil
@@ -111,43 +107,46 @@ func CheckIn(cfg config.ClientConfig) error {
func Leave(cfg config.ClientConfig) error {
err := functions.LeaveNetwork(cfg.Network)
if err != nil {
- log.Println("Error attempting to leave network " + cfg.Network)
+ ncutils.PrintLog("error attempting to leave network "+cfg.Network, 1)
+ } else {
+ ncutils.PrintLog("success", 0)
}
return err
}
func Push(cfg config.ClientConfig) error {
var err error
- if cfg.Network == "all" || netclientutils.IsWindows() {
- log.Println("No network selected. Running Push for all networks.")
+ if cfg.Network == "all" || ncutils.IsWindows() {
+ ncutils.PrintLog("pushing config to server for all networks.", 0)
networks, err := functions.GetNetworks()
if err != nil {
- log.Println("Error retrieving networks. Exiting.")
+ ncutils.PrintLog("error retrieving networks, exiting.", 0)
return err
}
for _, network := range networks {
err = functions.Push(network)
if err != nil {
- log.Printf("Error pushing network configs for "+network+" network: ", err)
+ log.Printf("error pushing network configs for "+network+" network: ", err)
} else {
- log.Println("pushed network config for " + network)
+ ncutils.PrintLog("pushed network config for "+network, 1)
}
}
err = nil
} else {
err = functions.Push(cfg.Network)
}
- log.Println("Completed pushing network configs to remote server.")
+ ncutils.PrintLog("completed pushing network configs to remote server", 1)
+ ncutils.PrintLog("success", 1)
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.")
+ ncutils.PrintLog("No network selected. Running Pull for all networks.", 0)
networks, err := functions.GetNetworks()
if err != nil {
- log.Println("Error retrieving networks. Exiting.")
+ ncutils.PrintLog("Error retrieving networks. Exiting.", 1)
return err
}
for _, network := range networks {
@@ -155,14 +154,15 @@ func Pull(cfg config.ClientConfig) error {
if err != nil {
log.Printf("Error pulling network config for "+network+" network: ", err)
} else {
- log.Println("pulled network config for " + network)
+ ncutils.PrintLog("pulled network config for "+network, 1)
}
}
err = nil
} else {
_, err = functions.Pull(cfg.Network, true)
}
- log.Println("Completed pulling network and peer configs.")
+ ncutils.PrintLog("reset network and peer configs", 1)
+ ncutils.PrintLog("success", 1)
return err
}
@@ -172,7 +172,7 @@ func List(cfg config.ClientConfig) error {
}
func Uninstall() error {
- log.Println("Uninstalling netclient")
+ ncutils.PrintLog("uninstalling netclient", 0)
err := functions.Uninstall()
return err
}
diff --git a/netclient/config/config.go b/netclient/config/config.go
index e28f84a9..34c1e828 100644
--- a/netclient/config/config.go
+++ b/netclient/config/config.go
@@ -8,8 +8,9 @@ import (
"fmt"
"log"
"os"
+
"github.com/gravitl/netmaker/models"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
@@ -25,7 +26,7 @@ type ClientConfig struct {
Network string `yaml:"network"`
Daemon string `yaml:"daemon"`
OperatingSystem string `yaml:"operatingsystem"`
- DebugJoin bool `yaml:"debugjoin"`
+ DebugJoin bool `yaml:"debugjoin"`
}
type ServerConfig struct {
CoreDNSAddr string `yaml:"corednsaddr"`
@@ -42,13 +43,13 @@ func Write(config *ClientConfig, network string) error {
err := errors.New("no network provided - exiting")
return err
}
- _, err := os.Stat(netclientutils.GetNetclientPath())
+ _, err := os.Stat(ncutils.GetNetclientPath())
if os.IsNotExist(err) {
- os.Mkdir(netclientutils.GetNetclientPath(), 0744)
+ os.Mkdir(ncutils.GetNetclientPath(), 0744)
} else if err != nil {
return err
}
- home := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
file := fmt.Sprintf(home + "netconfig-" + network)
f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
@@ -71,14 +72,14 @@ func WriteServer(server string, accesskey string, network string) error {
}
nofile := false
//home, err := homedir.Dir()
- _, err := os.Stat(netclientutils.GetNetclientPath())
+ _, err := os.Stat(ncutils.GetNetclientPath())
if os.IsNotExist(err) {
- os.Mkdir(netclientutils.GetNetclientPath(), 0744)
+ os.Mkdir(ncutils.GetNetclientPath(), 0744)
} else if err != nil {
- fmt.Println("couldnt find or create", netclientutils.GetNetclientPath())
+ fmt.Println("couldnt find or create", ncutils.GetNetclientPath())
return err
}
- home := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
file := fmt.Sprintf(home + "netconfig-" + network)
//f, err := os.Open(file)
@@ -151,7 +152,7 @@ func (config *ClientConfig) ReadConfig() {
nofile := false
//home, err := homedir.Dir()
- home := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
file := fmt.Sprintf(home + "netconfig-" + config.Network)
//f, err := os.Open(file)
f, err := os.OpenFile(file, os.O_RDONLY, 0666)
@@ -186,7 +187,7 @@ func ModConfig(node *models.Node) error {
}
var modconfig ClientConfig
var err error
- if FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network) {
+ if FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network) {
useconfig, err := ReadConfig(network)
if err != nil {
return err
@@ -306,7 +307,7 @@ func ReadConfig(network string) (*ClientConfig, error) {
return nil, err
}
nofile := false
- home := netclientutils.GetNetclientPathSpecific()
+ home := ncutils.GetNetclientPathSpecific()
file := fmt.Sprintf(home + "netconfig-" + network)
f, err := os.Open(file)
diff --git a/netclient/daemon/common.go b/netclient/daemon/common.go
new file mode 100644
index 00000000..30bf13e5
--- /dev/null
+++ b/netclient/daemon/common.go
@@ -0,0 +1,24 @@
+package daemon
+
+import (
+ "errors"
+ "runtime"
+
+ "github.com/gravitl/netmaker/netclient/config"
+)
+
+func InstallDaemon(cfg config.ClientConfig) error {
+ os := runtime.GOOS
+ var err error
+ switch os {
+ case "windows":
+ err = SetupWindowsDaemon()
+ case "darwin":
+ err = errors.New("need to implement macos daemon0")
+ case "linux":
+ err = SetupSystemDDaemon(cfg.Network)
+ default:
+ err = errors.New("this os is not yet supported for daemon mode. Run join cmd with flag '--daemon off'")
+ }
+ return err
+}
diff --git a/netclient/daemon/macos.go b/netclient/daemon/macos.go
new file mode 100644
index 00000000..0e0c34df
--- /dev/null
+++ b/netclient/daemon/macos.go
@@ -0,0 +1,76 @@
+package daemon
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "text/template"
+
+ "github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+const MAC_SERVICE_NAME = "com.gravitl.netclient"
+
+func CreateAndRunMacDaemon() error {
+ _, err := os.Stat("~/Library/LaunchAgents")
+ if os.IsNotExist(err) {
+ os.Mkdir("~/Library/LaunchAgents", 0744)
+ }
+ err = CreateMacService(MAC_SERVICE_NAME)
+ if err != nil {
+ return err
+ }
+ _, err = ncutils.RunCmd("launchctl load ~/Library/LaunchAgents/"+MAC_SERVICE_NAME+".plist", true)
+ return err
+}
+
+func CleanupMac() {
+ //StopWindowsDaemon()
+ //RemoveWindowsDaemon()
+ //os.RemoveAll(ncutils.GetNetclientPath())
+ log.Println("TODO: Not implemented yet")
+}
+
+func CreateMacService(servicename string) error {
+ tdata := MacTemplateData{
+ Label: servicename,
+ Program: "/etc/netclient/netclient",
+ KeepAlive: true,
+ RunAtLoad: true,
+ }
+ fileLoc := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), tdata.Label)
+ launchdFile, err := os.Open(fileLoc)
+ if err != nil {
+ return err
+ }
+ launchdTemplate := template.Must(template.New("launchdTemplate").Parse(MacTemplate()))
+ return launchdTemplate.Execute(launchdFile, tdata)
+}
+
+func MacTemplate() string {
+ return `
+
+
+
+
+ Label{{.Label}}
+ Program{{.Program}}
+ StandardOutPath/tmp/{{.Label}}.out.log
+ StandardErrorPath/tmp/{{.Label}}.err.log
+ KeepAlive<{{.KeepAlive}}/>
+ RunAtLoad<{{.RunAtLoad}}/>
+ StartCalendarInterval
+
+ Minute
+ */1
+
+
+`
+}
+
+type MacTemplateData struct {
+ Label string
+ Program string
+ KeepAlive bool
+ RunAtLoad bool
+}
diff --git a/netclient/daemon/systemd.go b/netclient/daemon/systemd.go
new file mode 100644
index 00000000..98a976a4
--- /dev/null
+++ b/netclient/daemon/systemd.go
@@ -0,0 +1,150 @@
+package daemon
+
+import (
+ //"github.com/davecgh/go-spew/spew"
+
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+
+ "github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+func SetupSystemDDaemon(network string) error {
+ if ncutils.IsWindows() {
+ return nil
+ }
+ 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 !ncutils.FileExists("/usr/local/bin/netclient") {
+ os.Symlink("/etc/netclient/netclient", "/usr/local/bin/netclient")
+ }
+ if !ncutils.FileExists("/etc/netclient/netclient") {
+ _, err = ncutils.Copy(binarypath, "/etc/netclient/netclient")
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+ }
+
+ systemservice := `[Unit]
+Description=Network Check
+Wants=netclient.timer
+
+[Service]
+Type=simple
+ExecStart=/etc/netclient/netclient checkin -n %i
+
+[Install]
+WantedBy=multi-user.target
+`
+
+ systemtimer := `[Unit]
+Description=Calls the Netmaker Mesh Client Service
+
+`
+ systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
+
+ systemtimer = systemtimer +
+ `
+
+[Timer]
+
+`
+ systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
+
+ systemtimer = systemtimer +
+ `
+
+OnCalendar=*:*:0/30
+
+[Install]
+WantedBy=timers.target
+`
+
+ servicebytes := []byte(systemservice)
+ timerbytes := []byte(systemtimer)
+
+ if !ncutils.FileExists("/etc/systemd/system/netclient@.service") {
+ err = ioutil.WriteFile("/etc/systemd/system/netclient@.service", servicebytes, 0644)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+ }
+
+ if !ncutils.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
+ }
+ }
+
+ _, _ = ncutils.RunCmd("systemctl enable netclient@.service", true)
+ _, _ = ncutils.RunCmd("systemctl daemon-reload", true)
+ _, _ = ncutils.RunCmd("systemctl enable netclient-"+network+".timer", true)
+ _, _ = ncutils.RunCmd("systemctl start netclient-"+network+".timer", true)
+ return nil
+}
+
+func RemoveSystemDServices(network string) error {
+ //sysExec, err := exec.LookPath("systemctl")
+ if !ncutils.IsWindows() {
+ fullremove, err := isOnlyService(network)
+ if err != nil {
+ log.Println(err)
+ }
+
+ if fullremove {
+ _, err = ncutils.RunCmd("systemctl disable netclient@.service", true)
+ }
+ _, _ = ncutils.RunCmd("systemctl daemon-reload", true)
+
+ if ncutils.FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
+ _, _ = ncutils.RunCmd("systemctl disable netclient-"+network+".timer", true)
+ }
+ if fullremove {
+ if ncutils.FileExists("/etc/systemd/system/netclient@.service") {
+ err = os.Remove("/etc/systemd/system/netclient@.service")
+ }
+ }
+ if ncutils.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)
+ }
+ _, _ = ncutils.RunCmd("systemctl daemon-reload", true)
+ _, _ = ncutils.RunCmd("systemctl reset-failed", true)
+ }
+ return nil
+}
+
+func isOnlyService(network string) (bool, error) {
+ isonly := false
+ files, err := filepath.Glob("/etc/netclient/netconfig-*")
+ if err != nil {
+ return isonly, err
+ }
+ count := len(files)
+ if count == 0 {
+ isonly = true
+ }
+ return isonly, err
+
+}
diff --git a/netclient/daemon/windows.go b/netclient/daemon/windows.go
new file mode 100644
index 00000000..5da7490d
--- /dev/null
+++ b/netclient/daemon/windows.go
@@ -0,0 +1,140 @@
+package daemon
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+ "strings"
+
+ "github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+func SetupWindowsDaemon() error {
+
+ if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
+ if err := writeServiceConfig(); err != nil {
+ return err
+ }
+ }
+
+ if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.exe") {
+ ncutils.Log("performing first time daemon setup")
+ if !ncutils.FileExists(".\\winsw.exe") {
+ err := downloadWinsw()
+ if err != nil {
+ return err
+ }
+ }
+ err := copyWinswOver()
+ if err != nil {
+ return err
+ }
+ ncutils.Log("finished daemon setup")
+ }
+ // install daemon, will not overwrite
+ ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe install`, true)
+ // start daemon, will not restart or start another
+ ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe start`, true)
+ ncutils.Log(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`)
+ return nil
+}
+
+func CleanupWindows() {
+ if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
+ writeServiceConfig()
+ }
+ StopWindowsDaemon()
+ RemoveWindowsDaemon()
+ os.RemoveAll(ncutils.GetNetclientPath())
+ log.Println("Netclient on Windows, uninstalled")
+}
+
+func writeServiceConfig() error {
+ serviceConfigPath := ncutils.GetNetclientPathSpecific() + "winsw.xml"
+ scriptString := fmt.Sprintf(`
+netclient
+Netclient
+Connects Windows nodes to one or more Netmaker networks.
+%v
+
+
+`, strings.Replace(ncutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
+ if !ncutils.FileExists(serviceConfigPath) {
+ err := ioutil.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
+ if err != nil {
+ return err
+ }
+ ncutils.Log("wrote the daemon config file to the Netclient directory")
+ }
+ return nil
+}
+
+// == Daemon ==
+func StopWindowsDaemon() {
+ ncutils.Log("no networks detected, stopping Windows, Netclient daemon")
+ // stop daemon, will not overwrite
+ ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe stop`, true)
+}
+
+func RemoveWindowsDaemon() {
+ // uninstall daemon, will not restart or start another
+ ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe uninstall`, true)
+ ncutils.Log("uninstalled Windows, Netclient daemon")
+}
+
+func copyWinswOver() error {
+
+ input, err := ioutil.ReadFile(".\\winsw.exe")
+ if err != nil {
+ ncutils.Log("failed to find winsw.exe")
+ return err
+ }
+ if err = ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"winsw.exe", input, 0644); err != nil {
+ ncutils.Log("failed to copy winsw.exe to " + ncutils.GetNetclientPath())
+ return err
+ }
+ if err = os.Remove(".\\winsw.exe"); err != nil {
+ ncutils.Log("failed to cleanup local winsw.exe, feel free to delete it")
+ return err
+ }
+ ncutils.Log("finished copying winsw.exe")
+ return nil
+}
+
+func downloadWinsw() error {
+ fullURLFile := "https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe"
+ fileName := "winsw.exe"
+
+ // Create the file
+ file, err := os.Create(fileName)
+ if err != nil {
+ ncutils.Log("could not create file on OS for Winsw")
+ return err
+ }
+ client := http.Client{
+ CheckRedirect: func(r *http.Request, via []*http.Request) error {
+ r.URL.Opaque = r.URL.Path
+ return nil
+ },
+ }
+ // Put content on file
+ ncutils.Log("downloading service tool...")
+ resp, err := client.Get(fullURLFile)
+ if err != nil {
+ ncutils.Log("could not GET Winsw")
+ return err
+ }
+ defer resp.Body.Close()
+
+ _, err = io.Copy(file, resp.Body)
+ if err != nil {
+ ncutils.Log("could not mount winsw.exe")
+ return err
+ }
+ defer file.Close()
+ ncutils.Log("finished downloading Winsw")
+ return nil
+}
diff --git a/netclient/functions/checkin.go b/netclient/functions/checkin.go
index 60ce628c..b885e0c6 100644
--- a/netclient/functions/checkin.go
+++ b/netclient/functions/checkin.go
@@ -3,7 +3,6 @@ package functions
import (
"encoding/json"
"errors"
- "log"
"os"
"runtime"
"strings"
@@ -13,7 +12,7 @@ import (
"github.com/gravitl/netmaker/netclient/auth"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/netclient/wireguard"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc"
@@ -30,37 +29,37 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
var err error
if node.Roaming == "yes" && node.IsStatic != "yes" {
if node.IsLocal == "no" {
- extIP, err := netclientutils.GetPublicIP()
+ extIP, err := ncutils.GetPublicIP()
if err != nil {
- log.Println("error encountered checking ip addresses:", err)
+ ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
}
if node.Endpoint != extIP && extIP != "" {
- log.Println("Endpoint has changed from " +
- node.Endpoint + " to " + extIP)
- log.Println("Updating address")
+ ncutils.PrintLog("endpoint has changed from "+
+ node.Endpoint+" to "+extIP, 1)
+ ncutils.PrintLog("updating address", 1)
node.Endpoint = extIP
ipchange = true
}
intIP, err := getPrivateAddr()
if err != nil {
- log.Println("error encountered checking ip addresses:", err)
+ ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
}
if node.LocalAddress != intIP && intIP != "" {
- log.Println("Local Address has changed from " +
- node.LocalAddress + " to " + intIP)
- log.Println("Updating address")
+ ncutils.PrintLog("local Address has changed from "+
+ node.LocalAddress+" to "+intIP, 1)
+ ncutils.PrintLog("updating address", 1)
node.LocalAddress = intIP
ipchange = true
}
} else {
- localIP, err := netclientutils.GetLocalIP(node.LocalRange)
+ localIP, err := ncutils.GetLocalIP(node.LocalRange)
if err != nil {
- log.Println("error encountered checking ip addresses:", err)
+ ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
}
if node.Endpoint != localIP && localIP != "" {
- log.Println("Endpoint has changed from " +
- node.Endpoint + " to " + localIP)
- log.Println("Updating address")
+ ncutils.PrintLog("endpoint has changed from "+
+ node.Endpoint+" to "+localIP, 1)
+ ncutils.PrintLog("updating address", 1)
node.Endpoint = localIP
node.LocalAddress = localIP
ipchange = true
@@ -70,12 +69,12 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
if ipchange {
err = config.ModConfig(node)
if err != nil {
- log.Println("Error:", err)
+ ncutils.PrintLog("error modifying config file: "+err.Error(), 1)
return false
}
err = wireguard.SetWGConfig(network, false)
if err != nil {
- log.Println("Error:", err)
+ ncutils.PrintLog("error setting wireguard config: "+err.Error(), 1)
return false
}
}
@@ -96,14 +95,14 @@ func checkNodeActions(node *models.Node, networkName string, servercfg config.Se
node.IsStatic != "yes" {
err := wireguard.SetWGKeyConfig(networkName, servercfg.GRPCAddress)
if err != nil {
- log.Println("Unable to process reset keys request:", err)
+ ncutils.PrintLog("unable to process reset keys request: "+err.Error(), 1)
return ""
}
}
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE {
err := RemoveLocalInstance(cfg, networkName)
if err != nil {
- log.Println("Error:", err)
+ ncutils.PrintLog("error deleting locally: "+err.Error(), 1)
}
return models.NODE_DELETE
}
@@ -161,22 +160,22 @@ func Pull(network string, manual bool) (*models.Node, error) {
servercfg := cfg.Server
var header metadata.MD
- if cfg.Node.IPForwarding == "yes" && !netclientutils.IsWindows() {
+ if cfg.Node.IPForwarding == "yes" && !ncutils.IsWindows() {
if err = local.SetIPForwarding(); err != nil {
return nil, err
}
}
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
- log.Println("Cant dial GRPC server:", err)
+ ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
return nil, err
}
wcclient := nodepb.NewNodeServiceClient(conn)
ctx, err := auth.SetJWT(wcclient, network)
if err != nil {
- log.Println("Failed to authenticate:", err)
+ ncutils.PrintLog("Failed to authenticate: "+err.Error(), 1)
return nil, err
}
@@ -198,7 +197,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
// check for interface change
if cfg.Node.Interface != resNode.Interface {
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
- log.Println("could not delete old interface", cfg.Node.Interface)
+ ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface, 1)
}
}
resNode.PullChanges = "no"
@@ -230,7 +229,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
}
}
}
- if netclientutils.IsLinux() {
+ if ncutils.IsLinux() {
setDNS(&resNode, servercfg, &cfg.Node)
}
@@ -249,16 +248,16 @@ func Push(network string) error {
var wcclient nodepb.NodeServiceClient
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
- log.Println("Cant dial GRPC server:", err)
+ ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
return err
}
wcclient = nodepb.NewNodeServiceClient(conn)
ctx, err := auth.SetJWT(wcclient, network)
if err != nil {
- log.Println("Failed to authenticate:", err)
+ ncutils.PrintLog("Failed to authenticate with server: "+err.Error(), 1)
return err
}
if postnode.IsPending != "yes" {
diff --git a/netclient/functions/common.go b/netclient/functions/common.go
index 989797ac..a352db1a 100644
--- a/netclient/functions/common.go
+++ b/netclient/functions/common.go
@@ -8,6 +8,7 @@ import (
"io/ioutil"
"log"
"net"
+ "os"
"os/exec"
"strings"
@@ -15,8 +16,9 @@ import (
"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/netclientutils"
+ "github.com/gravitl/netmaker/netclient/daemon"
+ "github.com/gravitl/netmaker/netclient/ncutils"
+ "github.com/gravitl/netmaker/netclient/wireguard"
"golang.zx2c4.com/wireguard/wgctrl"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
@@ -92,21 +94,21 @@ func GetNode(network string) models.Node {
func Uninstall() error {
networks, err := GetNetworks()
if err != nil {
- log.Println("unable to retrieve networks: ", err)
- log.Println("continuing uninstall without leaving networks")
+ ncutils.PrintLog("unable to retrieve networks: "+err.Error(), 1)
+ ncutils.PrintLog("continuing uninstall without leaving networks", 1)
} else {
for _, network := range networks {
err = LeaveNetwork(network)
if err != nil {
- log.Println("Encounter issue leaving network "+network+": ", err)
+ ncutils.PrintLog("Encounter issue leaving network "+network+": "+err.Error(), 1)
}
}
}
// clean up OS specific stuff
- if netclientutils.IsWindows() {
- local.CleanupWindows()
- } else if netclientutils.IsWindows() {
- local.CleanupMac()
+ if ncutils.IsWindows() {
+ daemon.CleanupWindows()
+ } else if ncutils.IsWindows() {
+ daemon.CleanupMac()
}
return err
@@ -123,7 +125,7 @@ func LeaveNetwork(network string) error {
var wcclient nodepb.NodeServiceClient
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
} else {
@@ -134,9 +136,9 @@ func LeaveNetwork(network string) error {
if err != nil {
log.Printf("Failed to authenticate: %v", err)
} else {
- if netclientutils.IsWindows() {
- local.RemoveWindowsConf(node.Interface)
- log.Println("removed Windows tunnel " + node.Interface)
+ if !ncutils.IsKernel() {
+ //wireguard.RemoveConf(node.Interface, true)
+ //ncutils.PrintLog("removed network tunnel "+node.Interface, 1)
}
node.SetID()
var header metadata.MD
@@ -149,10 +151,9 @@ func LeaveNetwork(network string) error {
grpc.Header(&header),
)
if err != nil {
- log.Printf("Encountered error deleting node: %v", err)
- log.Println(err)
+ ncutils.PrintLog("encountered error deleting node: "+err.Error(), 1)
} else {
- log.Println("Removed machine from " + node.Network + " network on remote server")
+ ncutils.PrintLog("removed machine from "+node.Network+" network on remote server", 1)
}
}
}
@@ -160,17 +161,19 @@ func LeaveNetwork(network string) error {
}
func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
- err := local.WipeLocal(networkName)
+ err := WipeLocal(networkName)
if err != nil {
- log.Printf("Unable to wipe local config: %v", err)
+ ncutils.PrintLog("unable to wipe local config", 1)
} else {
- log.Println("Removed " + networkName + " network locally")
+ ncutils.PrintLog("removed "+networkName+" network locally", 1)
}
if cfg.Daemon != "off" {
- if netclientutils.IsWindows() {
+ if ncutils.IsWindows() {
// TODO: Remove job?
+ } else if ncutils.IsMac() {
+ //TODO: Delete mac daemon
} else {
- err = local.RemoveSystemDServices(networkName)
+ err = daemon.RemoveSystemDServices(networkName)
}
}
return err
@@ -178,18 +181,18 @@ func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
func DeleteInterface(ifacename string, postdown string) error {
var err error
- if netclientutils.IsWindows() {
- err = local.RemoveWindowsConf(ifacename)
+ if !ncutils.IsKernel() {
+ err = wireguard.RemoveConf(ifacename, true)
} else {
ipExec, errN := exec.LookPath("ip")
err = errN
if err != nil {
- log.Println(err)
+ ncutils.PrintLog(err.Error(), 1)
}
- _, err = local.RunCmd(ipExec+" link del "+ifacename, false)
+ _, err = ncutils.RunCmd(ipExec+" link del "+ifacename, false)
if postdown != "" {
runcmds := strings.Split(postdown, "; ")
- err = local.RunCmds(runcmds, true)
+ err = ncutils.RunCmds(runcmds, true)
}
}
return err
@@ -212,9 +215,9 @@ func List() error {
"PrivateIPv6": cfg.Node.Address6,
"PublicEndpoint": cfg.Node.Endpoint,
})
- log.Println(network + ": " + string(jsoncfg))
+ fmt.Println(network + ": " + string(jsoncfg))
} else {
- log.Println(network + ": Could not retrieve network configuration.")
+ ncutils.PrintLog(network+": Could not retrieve network configuration.", 1)
}
}
return nil
@@ -222,7 +225,7 @@ func List() error {
func GetNetworks() ([]string, error) {
var networks []string
- files, err := ioutil.ReadDir(netclientutils.GetNetclientPath())
+ files, err := ioutil.ReadDir(ncutils.GetNetclientPath())
if err != nil {
return networks, err
}
@@ -247,3 +250,107 @@ func stringAfter(original string, substring string) string {
}
return original[adjustedPosition:len(original)]
}
+
+func WipeLocal(network string) error {
+ cfg, err := config.ReadConfig(network)
+ if err != nil {
+ return err
+ }
+ nodecfg := cfg.Node
+ ifacename := nodecfg.Interface
+
+ if ifacename != "" {
+ if !ncutils.IsKernel() {
+ if err = wireguard.RemoveConf(ifacename, true); err == nil {
+ ncutils.PrintLog("removed WireGuard interface: "+ifacename, 1)
+ }
+ } else {
+ ipExec, err := exec.LookPath("ip")
+ if err != nil {
+ return err
+ }
+ out, err := ncutils.RunCmd(ipExec+" link del "+ifacename, false)
+ dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
+ if err != nil && !dontprint {
+ ncutils.PrintLog("error running command: "+ipExec+" link del "+ifacename, 1)
+ ncutils.PrintLog(out, 1)
+ }
+ if nodecfg.PostDown != "" {
+ runcmds := strings.Split(nodecfg.PostDown, "; ")
+ _ = ncutils.RunCmds(runcmds, false)
+ }
+ }
+ }
+ home := ncutils.GetNetclientPathSpecific()
+ if ncutils.FileExists(home + "netconfig-" + network) {
+ _ = os.Remove(home + "netconfig-" + network)
+ }
+ if ncutils.FileExists(home + "nettoken-" + network) {
+ _ = os.Remove(home + "nettoken-" + network)
+ }
+ if ncutils.FileExists(home + "secret-" + network) {
+ _ = os.Remove(home + "secret-" + network)
+ }
+ if ncutils.FileExists(home + "wgkey-" + network) {
+ _ = os.Remove(home + "wgkey-" + network)
+ }
+ if ncutils.FileExists(home + "nm-" + network + ".conf") {
+ _ = os.Remove(home + "nm-" + network + ".conf")
+ }
+ return err
+}
+
+func getLocalIP(node models.Node) string {
+
+ var local string
+
+ ifaces, err := net.Interfaces()
+ if err != nil {
+ return local
+ }
+ _, localrange, err := net.ParseCIDR(node.LocalRange)
+ if err != nil {
+ return local
+ }
+
+ 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 local
+ }
+ for _, addr := range addrs {
+ var ip net.IP
+ switch v := addr.(type) {
+ case *net.IPNet:
+ if !found {
+ ip = v.IP
+ local = ip.String()
+ if node.IsLocal == "yes" {
+ found = localrange.Contains(ip)
+ } else {
+ found = true
+ }
+ }
+ case *net.IPAddr:
+ if !found {
+ ip = v.IP
+ local = ip.String()
+ if node.IsLocal == "yes" {
+ found = localrange.Contains(ip)
+
+ } else {
+ found = true
+ }
+ }
+ }
+ }
+ }
+ return local
+}
diff --git a/netclient/functions/install.go b/netclient/functions/install.go
deleted file mode 100644
index c9381046..00000000
--- a/netclient/functions/install.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package functions
-
-import (
- "github.com/gravitl/netmaker/netclient/config"
- "github.com/gravitl/netmaker/netclient/local"
-)
-
-func InstallDaemon(cfg config.ClientConfig) error {
-
- var err error
- err = local.ConfigureSystemD(cfg.Network)
- return err
-}
diff --git a/netclient/functions/join.go b/netclient/functions/join.go
index 7c37db07..e3f7cf90 100644
--- a/netclient/functions/join.go
+++ b/netclient/functions/join.go
@@ -11,8 +11,9 @@ import (
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/auth"
"github.com/gravitl/netmaker/netclient/config"
+ "github.com/gravitl/netmaker/netclient/daemon"
"github.com/gravitl/netmaker/netclient/local"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/netclient/server"
"github.com/gravitl/netmaker/netclient/wireguard"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@@ -27,7 +28,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
return err
}
- netclientutils.Log("attempting to join " + cfg.Network + " at " + cfg.Server.GRPCAddress)
+ ncutils.Log("joining " + cfg.Network + " at " + cfg.Server.GRPCAddress)
err := config.Write(&cfg, cfg.Network)
if err != nil {
return err
@@ -42,20 +43,20 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
cfg.Node.LocalAddress = getLocalIP(cfg.Node)
}
if cfg.Node.Password == "" {
- cfg.Node.Password = netclientutils.GenPass()
+ cfg.Node.Password = ncutils.GenPass()
}
auth.StoreSecret(cfg.Node.Password, cfg.Node.Network)
- // set endpoint if blank. set to local if local net, retrieve from function if not
+ // set endpoint if blank. set to local if local net, retrieve from function if not
if cfg.Node.Endpoint == "" {
if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
cfg.Node.Endpoint = cfg.Node.LocalAddress
} else {
- cfg.Node.Endpoint, err = netclientutils.GetPublicIP()
+ cfg.Node.Endpoint, err = ncutils.GetPublicIP()
}
if err != nil || cfg.Node.Endpoint == "" {
- netclientutils.Log("Error setting cfg.Node.Endpoint.")
+ ncutils.Log("Error setting cfg.Node.Endpoint.")
return err
}
}
@@ -71,7 +72,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
// Find and set node MacAddress
if cfg.Node.MacAddress == "" {
- macs, err := netclientutils.GetMacAddr()
+ macs, err := ncutils.GetMacAddr()
if err != nil {
return err
} else if len(macs) == 0 {
@@ -83,8 +84,8 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
var wcclient nodepb.NodeServiceClient
- conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ conn, err := grpc.Dial(cfg.Server.GRPCAddress,
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
log.Fatalf("Unable to establish client connection to "+cfg.Server.GRPCAddress+": %v", err)
@@ -129,7 +130,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
if err != nil {
return err
}
- log.Println("node created on remote server...updating configs")
+ ncutils.PrintLog("node created on remote server...updating configs", 1)
nodeData := res.Data
var node models.Node
@@ -138,14 +139,14 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
}
// get free port based on returned default listen port
- node.ListenPort, err = netclientutils.GetFreePort(node.ListenPort)
+ node.ListenPort, err = ncutils.GetFreePort(node.ListenPort)
if err != nil {
fmt.Printf("Error retrieving port: %v", err)
}
-
+
// safety check. If returned node from server is local, but not currently configured as local, set to local addr
if cfg.Node.IsLocal != "yes" && node.IsLocal == "yes" && node.LocalRange != "" {
- node.LocalAddress, err = netclientutils.GetLocalIP(node.LocalRange)
+ node.LocalAddress, err = ncutils.GetLocalIP(node.LocalRange)
if err != nil {
return err
}
@@ -161,45 +162,35 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
return err
}
- // pushing any local changes to server before starting wireguard
+ // pushing any local changes to server before starting wireguard
err = Push(cfg.Network)
if err != nil {
return err
}
if node.IsPending == "yes" {
- netclientutils.Log("Node is marked as PENDING.")
- netclientutils.Log("Awaiting approval from Admin before configuring WireGuard.")
+ ncutils.Log("Node is marked as PENDING.")
+ ncutils.Log("Awaiting approval from Admin before configuring WireGuard.")
if cfg.Daemon != "off" {
- if netclientutils.IsWindows() {
- // handle daemon here..
- err = local.CreateAndRunWindowsDaemon()
- } else {
- err = local.ConfigureSystemD(cfg.Network)
- }
- return err
+ return daemon.InstallDaemon(cfg)
}
}
- netclientutils.Log("retrieving remote peers")
+ ncutils.Log("retrieving remote peers")
peers, hasGateway, gateways, err := server.GetPeers(node.MacAddress, cfg.Network, cfg.Server.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
- if err != nil && !netclientutils.IsEmptyRecord(err) {
- netclientutils.Log("failed to retrieve peers")
+ if err != nil && !ncutils.IsEmptyRecord(err) {
+ ncutils.Log("failed to retrieve peers")
return err
}
- netclientutils.Log("starting wireguard")
+ ncutils.Log("starting wireguard")
err = wireguard.InitWireguard(&node, privateKey, peers, hasGateway, gateways)
if err != nil {
return err
}
if cfg.Daemon != "off" {
- if netclientutils.IsWindows() {
- err = local.CreateAndRunWindowsDaemon()
- } else {
- err = local.ConfigureSystemD(cfg.Network)
- }
+ err = daemon.InstallDaemon(cfg)
}
if err != nil {
return err
diff --git a/netclient/functions/joinutils.go b/netclient/functions/joinutils.go
deleted file mode 100644
index 10e32fbd..00000000
--- a/netclient/functions/joinutils.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package functions
-
-import (
- "github.com/gravitl/netmaker/models"
- "net"
-)
-
-
-func getLocalIP(node models.Node) string{
-
- var local string
-
- ifaces, err := net.Interfaces()
- if err != nil {
- return local
- }
- _, localrange, err := net.ParseCIDR(node.LocalRange)
- if err != nil {
- return local
- }
-
- 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 local
- }
- for _, addr := range addrs {
- var ip net.IP
- switch v := addr.(type) {
- case *net.IPNet:
- if !found {
- ip = v.IP
- local = ip.String()
- if node.IsLocal == "yes" {
- found = localrange.Contains(ip)
- } else {
- found = true
- }
- }
- case *net.IPAddr:
- if !found {
- ip = v.IP
- local = ip.String()
- if node.IsLocal == "yes" {
- found = localrange.Contains(ip)
-
- } else {
- found = true
- }
- }
- }
- }
- }
- return local
-}
diff --git a/netclient/functions/logging.go b/netclient/functions/logging.go
deleted file mode 100644
index 996bd75e..00000000
--- a/netclient/functions/logging.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package functions
-
-import (
- "log"
-)
-
-func PrintLog(message string, loglevel int) {
- log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
- if loglevel == 0 {
- log.Println(message)
- }
-}
\ No newline at end of file
diff --git a/netclient/local/dns.go b/netclient/local/dns.go
index 16519238..fef925a2 100644
--- a/netclient/local/dns.go
+++ b/netclient/local/dns.go
@@ -9,7 +9,7 @@ import (
"log"
"os/exec"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
)
func SetDNS(nameserver string) error {
@@ -34,7 +34,7 @@ func SetDNS(nameserver string) error {
}
func UpdateDNS(ifacename string, network string, nameserver string) error {
- if netclientutils.IsWindows() {
+ if ncutils.IsWindows() {
return nil
}
_, err := exec.LookPath("resolvectl")
@@ -42,15 +42,15 @@ func UpdateDNS(ifacename string, network string, nameserver string) error {
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, true)
+ _, err = ncutils.RunCmd("resolvectl domain "+ifacename+" ~"+network, true)
if err != nil {
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
} else {
- _, err = RunCmd("resolvectl default-route " + ifacename + " false", true)
+ _, err = ncutils.RunCmd("resolvectl default-route "+ifacename+" false", true)
if err != nil {
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
} else {
- _, err = RunCmd("resolvectl dns " + ifacename + " " + nameserver, true)
+ _, err = ncutils.RunCmd("resolvectl dns "+ifacename+" "+nameserver, true)
if err != nil {
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
}
diff --git a/netclient/local/local.go b/netclient/local/local.go
index 349e7fcc..87f81e5a 100644
--- a/netclient/local/local.go
+++ b/netclient/local/local.go
@@ -3,17 +3,11 @@ package local
import (
//"github.com/davecgh/go-spew/spew"
"errors"
- "io"
- "io/ioutil"
"log"
- "os"
- "os/exec"
- "path/filepath"
"runtime"
"strings"
- "github.com/gravitl/netmaker/netclient/config"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
)
func SetIPForwarding() error {
@@ -22,6 +16,8 @@ func SetIPForwarding() error {
switch os {
case "linux":
err = SetIPForwardingLinux()
+ case "darwin":
+ err = SetIPForwardingMac()
default:
err = errors.New("This OS is not supported")
}
@@ -29,14 +25,14 @@ func SetIPForwarding() error {
}
func SetIPForwardingLinux() error {
- out, err := RunCmd("sysctl net.ipv4.ip_forward", true)
+ out, err := ncutils.RunCmd("sysctl net.ipv4.ip_forward", true)
if err != nil {
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", true)
+ _, err = ncutils.RunCmd("sysctl -w net.ipv4.ip_forward=1", true)
if err != nil {
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
return err
@@ -46,274 +42,59 @@ func SetIPForwardingLinux() error {
return nil
}
-func RunCmd(command string, printerr bool) (string, error) {
- args := strings.Fields(command)
- out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
- if err != nil && printerr {
- log.Println("error running command:",command)
- log.Println(string(out))
- }
- return string(out), err
-}
-
-func RunCmds(commands []string, printerr bool) error {
- var err error
- for _, command := range commands {
- args := strings.Fields(command)
- out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
- if err != nil && printerr {
- log.Println("error running command:",command)
- log.Println(string(out))
- }
+func SetIPForwardingMac() error {
+ _, err := ncutils.RunCmd("sysctl -w net.inet.ip.forwarding=1", true)
+ if err != nil {
+ log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
}
return err
}
-func FileExists(f string) bool {
- info, err := os.Stat(f)
- if os.IsNotExist(err) {
+func IsWGInstalled() bool {
+ out, err := ncutils.RunCmd("wg help", true)
+ if err != nil {
return false
}
- return !info.IsDir()
+ return strings.Contains(out, "Available subcommand")
}
-func ConfigureSystemD(network string) error {
- /*
- path, err := os.Getwd()
- if err != nil {
- log.Println(err)
- return err
- }
- */
- //binarypath := path + "/netclient"
- if netclientutils.IsWindows() {
- return nil
- }
- dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
+func GetMacIface(addr string) (string, error) {
+ out, err := ncutils.RunCmd("route get "+addr, false)
+ var iface string
if err != nil {
- return err
+ return iface, errors.New(string(out))
}
- 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
+ for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
+ if strings.Contains(line, "interface: ") {
+ iface = getLineAfter(string(out), "interface: ")
+ iface = strings.Split(iface, "\n")[0]
+ break
}
}
-
- systemservice := `[Unit]
-Description=Network Check
-Wants=netclient.timer
-
-[Service]
-Type=simple
-ExecStart=/etc/netclient/netclient checkin -n %i
-
-[Install]
-WantedBy=multi-user.target
-`
-
- systemtimer := `[Unit]
-Description=Calls the Netmaker Mesh Client Service
-
-`
- systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
-
- systemtimer = systemtimer +
- `
-
-[Timer]
-
-`
- systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
-
- systemtimer = systemtimer +
- `
-
-OnCalendar=*:*:0/30
-
-[Install]
-WantedBy=timers.target
-`
-
- servicebytes := []byte(systemservice)
- 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
- }
+ if iface == "" {
+ err = errors.New("could not find iface for ip addr " + addr)
}
-
- 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
- }
- }
-
- _, _ = RunCmd("systemctl enable netclient@.service", true)
- _, _ = RunCmd("systemctl daemon-reload", true)
- _, _ = RunCmd("systemctl enable netclient-" + network + ".timer", true)
- _, _ = RunCmd("systemctl start netclient-" + network + ".timer", true)
- return nil
+ return iface, err
}
-func isOnlyService(network string) (bool, error) {
- isonly := false
- files, err := filepath.Glob("/etc/netclient/netconfig-*")
- if err != nil {
- return isonly, err
+func getLineAfter(value string, a string) string {
+ // Get substring after a string.
+ pos := strings.LastIndex(value, a)
+ if pos == -1 {
+ return ""
}
- count := len(files)
- if count == 0 {
- isonly = true
+ adjustedPos := pos + len(a)
+ if adjustedPos >= len(value) {
+ return ""
}
- return isonly, err
-
-}
-
-func RemoveSystemDServices(network string) error {
- //sysExec, err := exec.LookPath("systemctl")
- if !netclientutils.IsWindows() {
- fullremove, err := isOnlyService(network)
- if err != nil {
- log.Println(err)
- }
-
- if fullremove {
- _, err = RunCmd("systemctl disable netclient@.service", true)
- }
- _, _ = RunCmd("systemctl daemon-reload", true)
-
- if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
- _, _ = RunCmd("systemctl disable netclient-" + network + ".timer", true)
- }
- 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 err != nil {
- log.Println("Error removing file. Please investigate.")
- log.Println(err)
- }
- _, _ = RunCmd("systemctl daemon-reload", true)
- _, _ = RunCmd("systemctl reset-failed", true)
- }
- return nil
-}
-
-func WipeLocal(network string) error {
- cfg, err := config.ReadConfig(network)
- if err != nil {
- return err
- }
- nodecfg := cfg.Node
- ifacename := nodecfg.Interface
-
- home := netclientutils.GetNetclientPathSpecific()
- if FileExists(home + "netconfig-" + network) {
- _ = os.Remove(home + "netconfig-" + network)
- }
- if FileExists(home + "nettoken-" + network) {
- _ = os.Remove(home + "nettoken-" + network)
- }
- if FileExists(home + "secret-" + network) {
- _ = os.Remove(home + "secret-" + network)
- }
- if FileExists(home + "wgkey-" + network) {
- _ = os.Remove(home + "wgkey-" + network)
- }
- if FileExists(home + "nm-" + network + ".conf") {
- _ = os.Remove(home + "nm-" + network + ".conf")
- }
-
- if ifacename != "" {
- if netclientutils.IsWindows() {
- if err = RemoveWindowsConf(ifacename); err == nil {
- log.Println("removed Windows interface", ifacename)
- }
- } else {
- ipExec, err := exec.LookPath("ip")
- if err != nil {
- return err
- }
- out, err := RunCmd(ipExec + " link del " + ifacename, false)
- dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
- if err != nil && !dontprint {
- log.Println("error running command:",ipExec + " link del " + ifacename)
- log.Println(out)
- }
- if nodecfg.PostDown != "" {
- runcmds := strings.Split(nodecfg.PostDown, "; ")
- _ = RunCmds(runcmds, false)
- }
- }
- }
- return err
+ return value[adjustedPos:len(value)]
}
func HasNetwork(network string) bool {
- if netclientutils.IsWindows() {
- return FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network)
+ if ncutils.IsWindows() {
+ return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network)
}
- return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
- FileExists(netclientutils.GetNetclientPathSpecific()+"netconfig-"+network)
-}
-
-func copy(src, dst string) (int64, error) {
- 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")
- }
-
- 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)
- err = os.Chmod(dst, 0755)
- if err != nil {
- log.Println(err)
- }
- return nBytes, err
+ return ncutils.FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
+ ncutils.FileExists(ncutils.GetNetclientPathSpecific()+"netconfig-"+network)
}
diff --git a/netclient/local/windows.go b/netclient/local/windows.go
deleted file mode 100644
index 55bfb93a..00000000
--- a/netclient/local/windows.go
+++ /dev/null
@@ -1,175 +0,0 @@
-package local
-
-import (
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strings"
-
- "github.com/gravitl/netmaker/netclient/netclientutils"
-)
-
-func IsWindowsWGInstalled() bool {
- out, err := RunCmd("wg help", true)
- if err != nil {
- return false
- }
- return strings.Contains(out, "Available subcommand")
-}
-
-func ApplyWindowsConf(confPath string) error {
- if _, err := RunCmd("wireguard.exe /installtunnelservice "+confPath, true); err != nil {
- return err
- }
- return nil
-}
-
-func RemoveWindowsConf(ifacename string) error {
- if _, err := RunCmd("wireguard.exe /uninstalltunnelservice "+ifacename, true); err != nil {
- return err
- }
- return nil
-}
-
-func writeServiceConfig() error {
- serviceConfigPath := netclientutils.GetNetclientPathSpecific() + "winsw.xml"
- scriptString := fmt.Sprintf(`
-netclient
-Netclient
-Connects Windows nodes to one or more Netmaker networks.
-%v
-
-
-`, strings.Replace(netclientutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
- if !FileExists(serviceConfigPath) {
- err := ioutil.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
- if err != nil {
- return err
- }
- netclientutils.Log("wrote the daemon config file to the Netclient directory")
- }
- return nil
-}
-
-// == Daemon ==
-func StopWindowsDaemon() {
- netclientutils.Log("no networks detected, stopping Windows, Netclient daemon")
- // stop daemon, will not overwrite
- RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe stop`, true)
-}
-
-func RemoveWindowsDaemon() {
- // uninstall daemon, will not restart or start another
- RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe uninstall`, true)
- netclientutils.Log("uninstalled Windows, Netclient daemon")
-}
-
-func copyWinswOver() error {
-
- input, err := ioutil.ReadFile(".\\winsw.exe")
- if err != nil {
- netclientutils.Log("failed to find winsw.exe")
- return err
- }
- if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"winsw.exe", input, 0644); err != nil {
- netclientutils.Log("failed to copy winsw.exe to " + netclientutils.GetNetclientPath())
- return err
- }
- if err = os.Remove(".\\winsw.exe"); err != nil {
- netclientutils.Log("failed to cleanup local winsw.exe, feel free to delete it")
- return err
- }
- netclientutils.Log("finished copying winsw.exe")
- return nil
-}
-
-func downloadWinsw() error {
- fullURLFile := "https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe"
- fileName := "winsw.exe"
-
- // Create the file
- file, err := os.Create(fileName)
- if err != nil {
- netclientutils.Log("could not create file on OS for Winsw")
- return err
- }
- client := http.Client{
- CheckRedirect: func(r *http.Request, via []*http.Request) error {
- r.URL.Opaque = r.URL.Path
- return nil
- },
- }
- // Put content on file
- netclientutils.Log("downloading service tool...")
- resp, err := client.Get(fullURLFile)
- if err != nil {
- netclientutils.Log("could not GET Winsw")
- return err
- }
- defer resp.Body.Close()
-
- _, err = io.Copy(file, resp.Body)
- if err != nil {
- netclientutils.Log("could not mount winsw.exe")
- return err
- }
- defer file.Close()
- netclientutils.Log("finished downloading Winsw")
- return nil
-}
-
-func CreateAndRunMacDaemon() error {
- log.Println("TODO: Create Mac Daemon")
- return errors.New("no mac daemon yet")
-}
-
-func CreateAndRunWindowsDaemon() error {
-
- if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
- if err := writeServiceConfig(); err != nil {
- return err
- }
- }
-
- if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.exe") {
- netclientutils.Log("performing first time daemon setup")
- if !FileExists(".\\winsw.exe") {
- err := downloadWinsw()
- if err != nil {
- return err
- }
- }
- err := copyWinswOver()
- if err != nil {
- return err
- }
- netclientutils.Log("finished daemon setup")
- }
- // install daemon, will not overwrite
- RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe install`, true)
- // start daemon, will not restart or start another
- RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe start`, true)
- netclientutils.Log(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`)
- return nil
-}
-
-func CleanupWindows() {
- if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
- writeServiceConfig()
- }
- StopWindowsDaemon()
- RemoveWindowsDaemon()
- os.RemoveAll(netclientutils.GetNetclientPath())
- log.Println("Netclient on Windows, uninstalled")
-}
-
-func CleanupMac() {
- //StopWindowsDaemon()
- //RemoveWindowsDaemon()
- //os.RemoveAll(netclientutils.GetNetclientPath())
- log.Println("TODO: Not implemented yet")
-}
diff --git a/netclient/main.go b/netclient/main.go
index 69b26000..e8d91483 100644
--- a/netclient/main.go
+++ b/netclient/main.go
@@ -8,14 +8,15 @@ import (
"os"
"os/exec"
"os/signal"
+ "runtime/debug"
"strconv"
"syscall"
- "runtime/debug"
+
"github.com/gravitl/netmaker/netclient/command"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/netclient/ncwindows"
- "github.com/gravitl/netmaker/netclient/netclientutils"
"github.com/urfave/cli/v2"
)
@@ -23,7 +24,7 @@ func main() {
app := cli.NewApp()
app.Name = "Netclient CLI"
app.Usage = "Netmaker's netclient agent and CLI. Used to perform interactions with Netmaker server and set local WireGuard config."
- app.Version = "v0.7.3"
+ app.Version = "v0.8.0"
cliFlags := []cli.Flag{
&cli.StringFlag{
@@ -320,11 +321,11 @@ func main() {
setGarbageCollection()
- if netclientutils.IsWindows() {
+ if ncutils.IsWindows() {
ncwindows.InitWindows()
} else {
// start our application
- out, err := local.RunCmd("id -u", true)
+ out, err := ncutils.RunCmd("id -u", true)
if err != nil {
log.Fatal(out, err)
@@ -345,12 +346,12 @@ func main() {
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
}
}
- if netclientutils.IsWindows() {
- if !local.IsWindowsWGInstalled() {
- log.Fatal("Please install Windows WireGuard before using Gravitl Netclient. https://download.wireguard.com/windows-client/wireguard-installer.exe")
+ if !ncutils.IsKernel() {
+ if !local.IsWGInstalled() {
+ log.Fatal("Please install Windows WireGuard before using Gravitl Netclient. https://download.wireguard.com")
}
}
- if len(os.Args) == 1 && netclientutils.IsWindows() {
+ if len(os.Args) == 1 && ncutils.IsWindows() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
@@ -367,9 +368,9 @@ func main() {
}
}
-func setGarbageCollection(){
- _, gcset := os.LookupEnv("GOGC");
+func setGarbageCollection() {
+ _, gcset := os.LookupEnv("GOGC")
if !gcset {
- debug.SetGCPercent(netclientutils.DEFAULT_GC_PERCENT)
+ debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT)
}
-}
\ No newline at end of file
+}
diff --git a/netclient/netclientutils/netclientutils.go b/netclient/ncutils/netclientutils.go
similarity index 75%
rename from netclient/netclientutils/netclientutils.go
rename to netclient/ncutils/netclientutils.go
index 69c4f7dd..ff779f07 100644
--- a/netclient/netclientutils/netclientutils.go
+++ b/netclient/ncutils/netclientutils.go
@@ -1,15 +1,17 @@
-package netclientutils
+package ncutils
import (
"crypto/tls"
"errors"
"fmt"
+ "io"
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"os"
+ "os/exec"
"runtime"
"strconv"
"strings"
@@ -39,13 +41,20 @@ func IsWindows() bool {
}
func IsMac() bool {
- return runtime.GOOS == "macos"
+ return runtime.GOOS == "darwin"
}
func IsLinux() bool {
return runtime.GOOS == "linux"
}
+func IsKernel() bool {
+ //TODO
+ //Replace && true with some config file value
+ //This value should be something like kernelmode, which should be 'on' by default.
+ return IsLinux() && true
+}
+
// == database returned nothing error ==
func IsEmptyRecord(err error) bool {
if err == nil {
@@ -256,6 +265,8 @@ func GetHomeDirWindows() string {
func GetNetclientPath() string {
if IsWindows() {
return WINDOWS_APP_DATA_PATH
+ } else if IsMac() {
+ return "/etc/netclient/"
} else {
return LINUX_APP_DATA_PATH
}
@@ -264,6 +275,8 @@ func GetNetclientPath() string {
func GetNetclientPathSpecific() string {
if IsWindows() {
return WINDOWS_APP_DATA_PATH + "\\"
+ } else if IsMac() {
+ return "/etc/netclient/"
} else {
return LINUX_APP_DATA_PATH + "/"
}
@@ -278,3 +291,70 @@ func GRPCRequestOpts(isSecure string) grpc.DialOption {
}
return requestOpts
}
+
+func Copy(src, dst string) (int64, error) {
+ 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")
+ }
+
+ 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)
+ err = os.Chmod(dst, 0755)
+ if err != nil {
+ log.Println(err)
+ }
+ return nBytes, err
+}
+
+func RunCmd(command string, printerr bool) (string, error) {
+ args := strings.Fields(command)
+ out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
+ if err != nil && printerr {
+ log.Println("error running command:", command)
+ log.Println(strings.TrimSuffix(string(out), "\n"))
+ }
+ return string(out), err
+}
+
+func RunCmds(commands []string, printerr bool) error {
+ var err error
+ for _, command := range commands {
+ args := strings.Fields(command)
+ out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
+ if err != nil && printerr {
+ log.Println("error running command:", command)
+ log.Println(strings.TrimSuffix(string(out), "\n"))
+ }
+ }
+ return err
+}
+
+func FileExists(f string) bool {
+ info, err := os.Stat(f)
+ if os.IsNotExist(err) {
+ return false
+ }
+ return !info.IsDir()
+}
+
+func PrintLog(message string, loglevel int) {
+ log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
+ if loglevel < 2 {
+ log.Println("[netclient]", message)
+ }
+}
diff --git a/netclient/ncwindows/windows.go b/netclient/ncwindows/windows.go
index 388343e3..8ad127b4 100644
--- a/netclient/ncwindows/windows.go
+++ b/netclient/ncwindows/windows.go
@@ -5,21 +5,21 @@ import (
"log"
"os"
- "github.com/gravitl/netmaker/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
)
// Initialize windows directory & files and such
func InitWindows() {
- _, directoryErr := os.Stat(netclientutils.GetNetclientPath()) // Check if data directory exists or not
- if os.IsNotExist(directoryErr) { // create a data directory
- os.Mkdir(netclientutils.GetNetclientPath(), 0755)
+ _, directoryErr := os.Stat(ncutils.GetNetclientPath()) // Check if data directory exists or not
+ if os.IsNotExist(directoryErr) { // create a data directory
+ os.Mkdir(ncutils.GetNetclientPath(), 0755)
}
wdPath, wdErr := os.Getwd() // get the current working directory
if wdErr != nil {
log.Fatal("failed to get current directory..")
}
- _, dataNetclientErr := os.Stat(netclientutils.GetNetclientPathSpecific() + "netclient.exe")
+ _, dataNetclientErr := os.Stat(ncutils.GetNetclientPathSpecific() + "netclient.exe")
_, currentNetclientErr := os.Stat(wdPath + "\\netclient.exe")
if os.IsNotExist(dataNetclientErr) { // check and see if netclient.exe is in appdata
if currentNetclientErr == nil { // copy it if it exists locally
@@ -28,8 +28,8 @@ func InitWindows() {
log.Println("failed to find netclient.exe")
return
}
- if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
- log.Println("failed to copy netclient.exe to", netclientutils.GetNetclientPath())
+ if err = ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
+ log.Println("failed to copy netclient.exe to", ncutils.GetNetclientPath())
return
}
}
diff --git a/netclient/server/grpc.go b/netclient/server/grpc.go
index 10f16498..36b8c4d9 100644
--- a/netclient/server/grpc.go
+++ b/netclient/server/grpc.go
@@ -11,9 +11,8 @@ import (
nodepb "github.com/gravitl/netmaker/grpc"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/auth"
- "github.com/gravitl/netmaker/netclient/netclientutils"
"github.com/gravitl/netmaker/netclient/config"
- "github.com/gravitl/netmaker/netclient/local"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
@@ -24,8 +23,8 @@ const RELAY_KEEPALIVE_MARKER = "20007ms"
func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
var wcclient nodepb.NodeServiceClient
// == GRPC SETUP ==
- conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ conn, err := grpc.Dial(cfg.Server.GRPCAddress,
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
return nil, err
@@ -68,6 +67,7 @@ func CheckIn(network string) (*models.Node, error) {
return &node, err
}
+/*
func RemoveNetwork(network string) error {
//need to implement checkin on server side
cfg, err := config.ReadConfig(network)
@@ -79,8 +79,8 @@ func RemoveNetwork(network string) error {
log.Println("Deleting remote node with MAC: " + node.MacAddress)
var wcclient nodepb.NodeServiceClient
- conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ conn, err := grpc.Dial(cfg.Server.GRPCAddress,
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
//return err
@@ -110,16 +110,11 @@ func RemoveNetwork(network string) error {
}
}
}
- err = local.WipeLocal(network)
- if err != nil {
- log.Printf("Unable to wipe local config: %v", err)
- }
- if cfg.Daemon != "off" {
- err = local.RemoveSystemDServices(network)
- }
+ //err = functions.RemoveLocalInstance(network)
+
return err
}
-
+*/
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
hasGateway := false
var gateways []string
@@ -137,8 +132,8 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
}
- conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ conn, err := grpc.Dial(cfg.Server.GRPCAddress,
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
@@ -202,12 +197,12 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
allowedips = append(allowedips, *ipnet)
}
} else if appendip := net.ParseIP(allowedIp); appendip != nil && allowedIp != node.Address {
- ipnet := net.IPNet{
- IP: net.ParseIP(allowedIp),
- Mask: net.CIDRMask(32, 32),
- }
- allowedips = append(allowedips, ipnet)
- }
+ ipnet := net.IPNet{
+ IP: net.ParseIP(allowedIp),
+ Mask: net.CIDRMask(32, 32),
+ }
+ allowedips = append(allowedips, ipnet)
+ }
}
// handle egress gateway peers
if node.IsEgressGateway == "yes" {
@@ -273,7 +268,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
if err == nil {
peers = append(peers, extPeers...)
} else {
- log.Println("ERROR RETRIEVING EXTERNAL PEERS",err)
+ log.Println("ERROR RETRIEVING EXTERNAL PEERS", err)
}
}
return peers, hasGateway, gateways, err
@@ -287,8 +282,8 @@ func GetExtPeers(macaddress string, network string, server string, dualstack boo
}
nodecfg := cfg.Node
- conn, err := grpc.Dial(cfg.Server.GRPCAddress,
- netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
+ conn, err := grpc.Dial(cfg.Server.GRPCAddress,
+ ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
if err != nil {
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
}
diff --git a/netclient/wireguard/common.go b/netclient/wireguard/common.go
new file mode 100644
index 00000000..c0b12f07
--- /dev/null
+++ b/netclient/wireguard/common.go
@@ -0,0 +1,306 @@
+package wireguard
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/gravitl/netmaker/models"
+ "github.com/gravitl/netmaker/netclient/config"
+ "github.com/gravitl/netmaker/netclient/local"
+ "github.com/gravitl/netmaker/netclient/ncutils"
+ "github.com/gravitl/netmaker/netclient/server"
+ "golang.zx2c4.com/wireguard/wgctrl"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+ //homedir "github.com/mitchellh/go-homedir"
+)
+
+func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
+
+ client, err := wgctrl.New()
+ if err != nil {
+ ncutils.PrintLog("failed to start wgctrl", 0)
+ return err
+ }
+ device, err := client.Device(iface)
+ if err != nil {
+ ncutils.PrintLog("failed to parse interface", 0)
+ return err
+ }
+ devicePeers := device.Peers
+ if len(devicePeers) > 1 && len(peers) == 0 {
+ ncutils.PrintLog("no peers pulled", 1)
+ return err
+ }
+
+ for _, peer := range peers {
+
+ for _, currentPeer := range devicePeers {
+ if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
+ currentPeer.PublicKey.String() != peer.PublicKey.String() {
+ _, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
+ if err != nil {
+ log.Println("error removing peer", peer.Endpoint.String())
+ }
+ }
+ }
+ udpendpoint := peer.Endpoint.String()
+ var allowedips string
+ var iparr []string
+ for _, ipaddr := range peer.AllowedIPs {
+ iparr = append(iparr, ipaddr.String())
+ }
+ allowedips = strings.Join(iparr, ",")
+ keepAliveString := strconv.Itoa(int(keepalive))
+ if keepAliveString == "0" {
+ keepAliveString = "5"
+ }
+ if peer.Endpoint != nil {
+ _, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
+ " endpoint "+udpendpoint+
+ " persistent-keepalive "+keepAliveString+
+ " allowed-ips "+allowedips, true)
+ } else {
+ _, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
+ " persistent-keepalive "+keepAliveString+
+ " allowed-ips "+allowedips, true)
+ }
+ if err != nil {
+ log.Println("error setting peer", peer.PublicKey.String())
+ }
+ }
+
+ for _, currentPeer := range devicePeers {
+ shouldDelete := true
+ for _, peer := range peers {
+ if peer.AllowedIPs[0].String() == currentPeer.AllowedIPs[0].String() {
+ shouldDelete = false
+ }
+ }
+ if shouldDelete {
+ output, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
+ if err != nil {
+ log.Println(output, "error removing peer", currentPeer.PublicKey.String())
+ }
+ }
+ }
+
+ return nil
+}
+
+func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
+
+ key, err := wgtypes.ParseKey(privkey)
+ if err != nil {
+ return err
+ }
+
+ wgclient, err := wgctrl.New()
+ if err != nil {
+ return err
+ }
+ modcfg, err := config.ReadConfig(node.Network)
+ if err != nil {
+ return err
+ }
+ nodecfg := modcfg.Node
+ servercfg := modcfg.Server
+
+ if err != nil {
+ log.Fatalf("failed to open client: %v", err)
+ }
+ defer wgclient.Close()
+
+ ifacename := node.Interface
+ if nodecfg.Interface != "" {
+ ifacename = nodecfg.Interface
+ } else if node.Interface != "" {
+ ifacename = node.Interface
+ } else {
+ log.Fatal("no interface to configure")
+ }
+ if node.Address == "" {
+ log.Fatal("no address to configure")
+ }
+ nameserver := servercfg.CoreDNSAddr
+ network := node.Network
+ if nodecfg.Network != "" {
+ network = nodecfg.Network
+ } else if node.Network != "" {
+ network = node.Network
+ }
+
+ if ncutils.IsKernel() {
+ setKernelDevice(ifacename, node.Address)
+ }
+
+ var nodeport int
+ nodeport = int(node.ListenPort)
+ conf := wgtypes.Config{}
+ if nodecfg.UDPHolePunch == "yes" &&
+ nodecfg.IsServer == "no" &&
+ nodecfg.IsIngressGateway != "yes" &&
+ nodecfg.IsStatic != "yes" {
+ conf = wgtypes.Config{
+ PrivateKey: &key,
+ ReplacePeers: true,
+ Peers: peers,
+ }
+ } else {
+ conf = wgtypes.Config{
+ PrivateKey: &key,
+ ListenPort: &nodeport,
+ ReplacePeers: true,
+ Peers: peers,
+ }
+ }
+ if !ncutils.IsKernel() {
+ var newConf string
+ if node.UDPHolePunch != "yes" {
+ newConf, _ = ncutils.CreateUserSpaceConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, node.PersistentKeepalive, peers)
+ } else {
+ newConf, _ = ncutils.CreateUserSpaceConf(node.Address, key.String(), "", node.MTU, node.PersistentKeepalive, peers)
+ }
+ confPath := ncutils.GetNetclientPathSpecific() + node.Interface + ".conf"
+ ncutils.PrintLog("writing wg conf file to: "+confPath, 1)
+ err = ioutil.WriteFile(confPath, []byte(newConf), 0644)
+ if err != nil {
+ ncutils.PrintLog("error writing wg conf file to "+confPath+": "+err.Error(), 1)
+ return err
+ }
+ // spin up userspace / windows interface + apply the conf file
+ _ = RemoveConf(node.Interface, false) // remove interface first
+ err = ApplyConf(confPath)
+ if err != nil {
+ ncutils.PrintLog("failed to create wireguard interface", 1)
+ return err
+ }
+ } else {
+ ipExec, err := exec.LookPath("ip")
+ if err != nil {
+ return err
+ }
+
+ _, err = wgclient.Device(ifacename)
+ if err != nil {
+ if os.IsNotExist(err) {
+ fmt.Println("Device does not exist: ")
+ fmt.Println(err)
+ } else {
+ log.Fatalf("Unknown config error: %v", err)
+ }
+ }
+
+ err = wgclient.ConfigureDevice(ifacename, conf)
+ if err != nil {
+ if os.IsNotExist(err) {
+ fmt.Println("Device does not exist: ")
+ fmt.Println(err)
+ } else {
+ fmt.Printf("This is inconvenient: %v", err)
+ }
+ }
+
+ //=========DNS Setup==========\\
+ if nodecfg.DNSOn == "yes" {
+ _ = local.UpdateDNS(ifacename, network, nameserver)
+ }
+ //=========End DNS Setup=======\\
+ if _, err := ncutils.RunCmd(ipExec+" link set down dev "+ifacename, false); err != nil {
+ ncutils.Log("attempted to remove interface before editing")
+ return err
+ }
+
+ if nodecfg.PostDown != "" {
+ runcmds := strings.Split(nodecfg.PostDown, "; ")
+ _ = ncutils.RunCmds(runcmds, true)
+ }
+ // set MTU of node interface
+ if _, err := ncutils.RunCmd(ipExec+" link set mtu "+strconv.Itoa(int(nodecfg.MTU))+" up dev "+ifacename, true); err != nil {
+ ncutils.Log("failed to create interface with mtu " + ifacename)
+ return err
+ }
+
+ if nodecfg.PostUp != "" {
+ runcmds := strings.Split(nodecfg.PostUp, "; ")
+ _ = ncutils.RunCmds(runcmds, true)
+ }
+ if hasGateway {
+ for _, gateway := range gateways {
+ _, _ = ncutils.RunCmd(ipExec+" -4 route add "+gateway+" dev "+ifacename, true)
+ }
+ }
+ if node.Address6 != "" && node.IsDualStack == "yes" {
+ log.Println("[netclient] adding address: "+node.Address6, 1)
+ _, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+node.Address6+"/64", true)
+ }
+ }
+ return err
+}
+
+func SetWGConfig(network string, peerupdate bool) error {
+
+ cfg, err := config.ReadConfig(network)
+ if err != nil {
+ return err
+ }
+ servercfg := cfg.Server
+ nodecfg := cfg.Node
+
+ peers, hasGateway, gateways, err := server.GetPeers(nodecfg.MacAddress, nodecfg.Network, servercfg.GRPCAddress, nodecfg.IsDualStack == "yes", nodecfg.IsIngressGateway == "yes")
+ if err != nil {
+ return err
+ }
+ privkey, err := RetrievePrivKey(network)
+ if err != nil {
+ return err
+ }
+ if peerupdate {
+ var iface string
+ iface = nodecfg.Interface
+ if ncutils.IsMac() {
+ iface, err = local.GetMacIface(nodecfg.Address)
+ if err != nil {
+ return err
+ }
+ }
+ err = SetPeers(iface, nodecfg.PersistentKeepalive, peers)
+ } else {
+ err = InitWireguard(&nodecfg, privkey, peers, hasGateway, gateways)
+ }
+ if err != nil {
+ return err
+ }
+
+ return err
+}
+
+func RemoveConf(iface string, printlog bool) error {
+ os := runtime.GOOS
+ var err error
+ switch os {
+ case "windows":
+ err = RemoveWindowsConf(iface, printlog)
+ default:
+ confPath := ncutils.GetNetclientPathSpecific() + iface + ".conf"
+ err = RemoveWGQuickConf(confPath, printlog)
+ }
+ return err
+}
+
+func ApplyConf(confPath string) error {
+ os := runtime.GOOS
+ var err error
+ switch os {
+ case "windows":
+ err = ApplyWindowsConf(confPath)
+ default:
+ err = ApplyWGQuickConf(confPath)
+ }
+ return err
+}
diff --git a/netclient/wireguard/kernel.go b/netclient/wireguard/kernel.go
index cd7d1cbf..d2466142 100644
--- a/netclient/wireguard/kernel.go
+++ b/netclient/wireguard/kernel.go
@@ -1,325 +1,21 @@
package wireguard
import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
"os/exec"
- "strconv"
- "strings"
- "github.com/gravitl/netmaker/models"
- "github.com/gravitl/netmaker/netclient/config"
- "github.com/gravitl/netmaker/netclient/local"
- "github.com/gravitl/netmaker/netclient/netclientutils"
- "github.com/gravitl/netmaker/netclient/server"
- "golang.zx2c4.com/wireguard/wgctrl"
- "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+ "github.com/gravitl/netmaker/netclient/ncutils"
//homedir "github.com/mitchellh/go-homedir"
)
-func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
-
- key, err := wgtypes.ParseKey(privkey)
+func setKernelDevice(ifacename string, address string) error {
+ ipExec, err := exec.LookPath("ip")
if err != nil {
return err
}
- wgclient, err := wgctrl.New()
- if err != nil {
- return err
- }
- modcfg, err := config.ReadConfig(node.Network)
- if err != nil {
- return err
- }
- nodecfg := modcfg.Node
- servercfg := modcfg.Server
-
- if err != nil {
- log.Fatalf("failed to open client: %v", err)
- }
- defer wgclient.Close()
-
- ifacename := node.Interface
- if nodecfg.Interface != "" {
- ifacename = nodecfg.Interface
- } else if node.Interface != "" {
- ifacename = node.Interface
- } else {
- log.Fatal("no interface to configure")
- }
- if node.Address == "" {
- log.Fatal("no address to configure")
- }
- nameserver := servercfg.CoreDNSAddr
- network := node.Network
- if nodecfg.Network != "" {
- network = nodecfg.Network
- } else if node.Network != "" {
- network = node.Network
- }
-
- if !netclientutils.IsWindows() {
-
- ipExec, err := exec.LookPath("ip")
- if err != nil {
- return err
- }
-
- _, _ = local.RunCmd("ip link delete dev " + ifacename, false)
- _, _ = local.RunCmd(ipExec + " link add dev " + ifacename + " type wireguard", true)
- _, _ = local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address + "/24", true)
- }
- var nodeport int
- nodeport = int(node.ListenPort)
- conf := wgtypes.Config{}
- if nodecfg.UDPHolePunch == "yes" &&
- nodecfg.IsServer == "no" &&
- nodecfg.IsIngressGateway != "yes" &&
- nodecfg.IsStatic != "yes" {
- conf = wgtypes.Config{
- PrivateKey: &key,
- ReplacePeers: true,
- Peers: peers,
- }
- } else {
- conf = wgtypes.Config{
- PrivateKey: &key,
- ListenPort: &nodeport,
- ReplacePeers: true,
- Peers: peers,
- }
- }
- if netclientutils.IsWindows() {
- var newConf string
- if node.UDPHolePunch != "yes" {
- newConf, _ = netclientutils.CreateUserSpaceConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, node.PersistentKeepalive, peers)
- } else {
- newConf, _ = netclientutils.CreateUserSpaceConf(node.Address, key.String(), "", node.MTU, node.PersistentKeepalive, peers)
- }
- confPath := netclientutils.GetNetclientPathSpecific() + node.Interface + ".conf"
- err = ioutil.WriteFile(confPath, []byte(newConf), 0644)
- if err != nil {
- return err
- }
- // spin up userspace / windows interface + apply the conf file
- err := local.RemoveWindowsConf(node.Interface) // remove interface first
- if err != nil {
- log.Println("attempted to remove pre-existing windows interface before updating")
- }
- local.ApplyWindowsConf(confPath)
- } else {
- ipExec, err := exec.LookPath("ip")
- if err != nil {
- return err
- }
-
- _, err = wgclient.Device(ifacename)
- if err != nil {
- if os.IsNotExist(err) {
- fmt.Println("Device does not exist: ")
- fmt.Println(err)
- } else {
- log.Fatalf("Unknown config error: %v", err)
- }
- }
-
- err = wgclient.ConfigureDevice(ifacename, conf)
- if err != nil {
- if os.IsNotExist(err) {
- fmt.Println("Device does not exist: ")
- fmt.Println(err)
- } else {
- fmt.Printf("This is inconvenient: %v", err)
- }
- }
-
- //=========DNS Setup==========\\
- if nodecfg.DNSOn == "yes" {
- _ = local.UpdateDNS(ifacename, network, nameserver)
- }
- //=========End DNS Setup=======\\
- if _, err := local.RunCmd(ipExec + " link set down dev " + ifacename, false); err != nil {
- netclientutils.Log("attempted to remove interface before editing")
- return err
- }
-
- if nodecfg.PostDown != "" {
- runcmds := strings.Split(nodecfg.PostDown, "; ")
- err = local.RunCmds(runcmds, true)
- }
- // set MTU of node interface
- if _, err := local.RunCmd(ipExec + " link set mtu " + strconv.Itoa(int(nodecfg.MTU)) + " up dev " + ifacename, true); err != nil {
- netclientutils.Log("failed to create interface with mtu " + ifacename)
- return err
- }
-
- if nodecfg.PostUp != "" {
- runcmds := strings.Split(nodecfg.PostUp, "; ")
- err = local.RunCmds(runcmds, true)
- }
- if hasGateway {
- for _, gateway := range gateways {
- _, _ = local.RunCmd(ipExec + " -4 route add " + gateway + " dev " + ifacename, true)
- }
- }
- if node.Address6 != "" && node.IsDualStack == "yes" {
- log.Println("[netclient] adding address: " + node.Address6, 1)
- _, _ = local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address6 + "/64", true)
- }
- }
- return err
-}
-
-func SetWGKeyConfig(network string, serveraddr string) error {
-
- cfg, err := config.ReadConfig(network)
- if err != nil {
- return err
- }
-
- node := cfg.Node
-
- privatekey, err := wgtypes.GeneratePrivateKey()
- if err != nil {
- return err
- }
- privkeystring := privatekey.String()
- publickey := privatekey.PublicKey()
-
- node.PublicKey = publickey.String()
-
- err = StorePrivKey(privkeystring, network)
- if err != nil {
- return err
- }
- if node.Action == models.NODE_UPDATE_KEY {
- node.Action = models.NODE_NOOP
- }
- err = config.ModConfig(&node)
- if err != nil {
- return err
- }
-
- err = SetWGConfig(network, false)
- if err != nil {
- return err
- }
-
- return err
-}
-
-func SetWGConfig(network string, peerupdate bool) error {
-
- cfg, err := config.ReadConfig(network)
- if err != nil {
- return err
- }
- servercfg := cfg.Server
- nodecfg := cfg.Node
-
- peers, hasGateway, gateways, err := server.GetPeers(nodecfg.MacAddress, nodecfg.Network, servercfg.GRPCAddress, nodecfg.IsDualStack == "yes", nodecfg.IsIngressGateway == "yes")
- if err != nil {
- return err
- }
- privkey, err := RetrievePrivKey(network)
- if err != nil {
- return err
- }
- if peerupdate {
- err = SetPeers(nodecfg.Interface, nodecfg.PersistentKeepalive, peers)
- } else {
- err = InitWireguard(&nodecfg, privkey, peers, hasGateway, gateways)
- }
- if err != nil {
- return err
- }
-
- return err
-}
-
-func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
-
- client, err := wgctrl.New()
- if err != nil {
- log.Println("failed to start wgctrl")
- return err
- }
- device, err := client.Device(iface)
- if err != nil {
- log.Println("failed to parse interface")
- return err
- }
- devicePeers := device.Peers
- if len(devicePeers) > 1 && len(peers) == 0 {
- log.Println("no peers pulled")
- return err
- }
-
- for _, peer := range peers {
-
- for _, currentPeer := range devicePeers {
- 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() + " remove", true)
- if err != nil {
- log.Println("error removing peer", peer.Endpoint.String())
- }
- }
- }
- udpendpoint := peer.Endpoint.String()
- var allowedips string
- var iparr []string
- for _, ipaddr := range peer.AllowedIPs {
- iparr = append(iparr, ipaddr.String())
- }
- allowedips = strings.Join(iparr, ",")
- keepAliveString := strconv.Itoa(int(keepalive))
- if keepAliveString == "0" {
- keepAliveString = "5"
- }
- if peer.Endpoint != nil {
- _, err = local.RunCmd("wg set " + iface + " peer " + peer.PublicKey.String() +
- " endpoint " + udpendpoint +
- " persistent-keepalive " + keepAliveString +
- " allowed-ips " + allowedips, true)
- } else {
- _, err = local.RunCmd("wg set " + iface + " peer " + peer.PublicKey.String() +
- " persistent-keepalive " + keepAliveString +
- " allowed-ips " + allowedips, true)
- }
- if err != nil {
- log.Println("error setting peer", peer.PublicKey.String())
- }
- }
-
- for _, currentPeer := range devicePeers {
- shouldDelete := true
- for _, peer := range peers {
- if peer.AllowedIPs[0].String() == currentPeer.AllowedIPs[0].String() {
- shouldDelete = false
- }
- }
- if shouldDelete {
- output, err := local.RunCmd("wg set " + iface + " peer " + currentPeer.PublicKey.String() + " remove", true)
- if err != nil {
- log.Println(output, "error removing peer", currentPeer.PublicKey.String())
- }
- }
- }
+ _, _ = ncutils.RunCmd("ip link delete dev "+ifacename, false)
+ _, _ = ncutils.RunCmd(ipExec+" link add dev "+ifacename+" type wireguard", true)
+ _, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+address+"/24", true)
return nil
}
-
-func StorePrivKey(key string, network string) error {
- d1 := []byte(key)
- err := ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
- return err
-}
-
-func RetrievePrivKey(network string) (string, error) {
- dat, err := ioutil.ReadFile(netclientutils.GetNetclientPathSpecific() + "wgkey-" + network)
- return string(dat), err
-}
diff --git a/netclient/wireguard/unix.go b/netclient/wireguard/unix.go
new file mode 100644
index 00000000..a4d67a03
--- /dev/null
+++ b/netclient/wireguard/unix.go
@@ -0,0 +1,74 @@
+package wireguard
+
+import (
+ "io/ioutil"
+
+ "github.com/gravitl/netmaker/models"
+ "github.com/gravitl/netmaker/netclient/config"
+ "github.com/gravitl/netmaker/netclient/ncutils"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+ //homedir "github.com/mitchellh/go-homedir"
+)
+
+func SetWGKeyConfig(network string, serveraddr string) error {
+
+ cfg, err := config.ReadConfig(network)
+ if err != nil {
+ return err
+ }
+
+ node := cfg.Node
+
+ privatekey, err := wgtypes.GeneratePrivateKey()
+ if err != nil {
+ return err
+ }
+ privkeystring := privatekey.String()
+ publickey := privatekey.PublicKey()
+
+ node.PublicKey = publickey.String()
+
+ err = StorePrivKey(privkeystring, network)
+ if err != nil {
+ return err
+ }
+ if node.Action == models.NODE_UPDATE_KEY {
+ node.Action = models.NODE_NOOP
+ }
+ err = config.ModConfig(&node)
+ if err != nil {
+ return err
+ }
+
+ err = SetWGConfig(network, false)
+ if err != nil {
+ return err
+ }
+
+ return err
+}
+
+func ApplyWGQuickConf(confPath string) error {
+ if _, err := ncutils.RunCmd("wg-quick up "+confPath, true); err != nil {
+ return err
+ }
+ return nil
+}
+
+func RemoveWGQuickConf(confPath string, printlog bool) error {
+ if _, err := ncutils.RunCmd("wg-quick down "+confPath, printlog); err != nil {
+ return err
+ }
+ return nil
+}
+
+func StorePrivKey(key string, network string) error {
+ d1 := []byte(key)
+ err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
+ return err
+}
+
+func RetrievePrivKey(network string) (string, error) {
+ dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "wgkey-" + network)
+ return string(dat), err
+}
diff --git a/netclient/wireguard/windows.go b/netclient/wireguard/windows.go
new file mode 100644
index 00000000..7f00048f
--- /dev/null
+++ b/netclient/wireguard/windows.go
@@ -0,0 +1,17 @@
+package wireguard
+
+import "github.com/gravitl/netmaker/netclient/ncutils"
+
+func ApplyWindowsConf(confPath string) error {
+ if _, err := ncutils.RunCmd("wireguard.exe /installtunnelservice "+confPath, true); err != nil {
+ return err
+ }
+ return nil
+}
+
+func RemoveWindowsConf(ifacename string, printlog bool) error {
+ if _, err := ncutils.RunCmd("wireguard.exe /uninstalltunnelservice "+ifacename, printlog); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go
index 377e16b6..1268778e 100644
--- a/servercfg/serverconf.go
+++ b/servercfg/serverconf.go
@@ -73,7 +73,7 @@ func GetAPIConnString() string {
return conn
}
func GetVersion() string {
- version := "0.7.3"
+ version := "0.8.0"
if config.Config.Server.Version != "" {
version = config.Config.Server.Version
}
diff --git a/serverctl/serverctl.go b/serverctl/serverctl.go
index a23c5960..fc99d4ce 100644
--- a/serverctl/serverctl.go
+++ b/serverctl/serverctl.go
@@ -11,8 +11,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/netclient/netclientutils"
+ "github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
)
@@ -33,10 +32,10 @@ func GetServerWGConf() (models.IntClient, error) {
func InstallNetclient() error {
- netclientPath := netclientutils.GetNetclientPathSpecific()
+ netclientPath := ncutils.GetNetclientPathSpecific()
if !FileExists(netclientPath + "netclient") {
var err error
- if netclientutils.IsWindows() {
+ if ncutils.IsWindows() {
_, err = copy(".\\netclient\\netclient", netclientPath+"netclient")
} else {
_, err = copy("./netclient/netclient", netclientPath+"netclient")
@@ -87,13 +86,13 @@ func copy(src, dst string) (int64, error) {
}
func RemoveNetwork(network string) (bool, error) {
- netclientPath := netclientutils.GetNetclientPathSpecific()
+ netclientPath := ncutils.GetNetclientPathSpecific()
_, err := os.Stat(netclientPath + "netclient")
if err != nil {
log.Println("could not find " + netclientPath + "netclient")
return false, err
}
- _, err = local.RunCmd(netclientPath+"netclient leave -n "+network, true)
+ _, err = ncutils.RunCmd(netclientPath+"netclient leave -n "+network, true)
if err == nil {
log.Println("Server removed from network " + network)
}
@@ -107,8 +106,8 @@ func AddNetwork(network string) (bool, error) {
log.Println("could not get public IP.")
return false, err
}
- netclientDir := netclientutils.GetNetclientPath()
- netclientPath := netclientutils.GetNetclientPathSpecific()
+ netclientDir := ncutils.GetNetclientPath()
+ netclientPath := ncutils.GetNetclientPathSpecific()
_, err = os.Stat(netclientDir)
if os.IsNotExist(err) {
os.Mkdir(netclientDir, 744)