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)