diff --git a/cli/cmd/network/create.go b/cli/cmd/network/create.go index 25fbf469..5cd8e264 100644 --- a/cli/cmd/network/create.go +++ b/cli/cmd/network/create.go @@ -35,9 +35,6 @@ var networkCreateCmd = &cobra.Command{ if udpHolePunch { network.DefaultUDPHolePunch = "yes" } - if localNetwork { - network.IsLocal = "yes" - } if defaultACL { network.DefaultACL = "yes" } @@ -62,7 +59,6 @@ func init() { networkCreateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network") networkCreateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network") networkCreateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?") - networkCreateCmd.Flags().BoolVar(&localNetwork, "local", false, "Is the network local (LAN) ?") networkCreateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?") networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface") networkCreateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients") diff --git a/cli/cmd/network/flags.go b/cli/cmd/network/flags.go index 2ece05aa..26e564f2 100644 --- a/cli/cmd/network/flags.go +++ b/cli/cmd/network/flags.go @@ -6,7 +6,6 @@ var ( address string address6 string udpHolePunch bool - localNetwork bool defaultACL bool defaultInterface string defaultListenPort int diff --git a/cli/cmd/network/update.go b/cli/cmd/network/update.go index 7f1e3d55..94987cdc 100644 --- a/cli/cmd/network/update.go +++ b/cli/cmd/network/update.go @@ -38,9 +38,6 @@ var networkUpdateCmd = &cobra.Command{ if udpHolePunch { network.DefaultUDPHolePunch = "yes" } - if localNetwork { - network.IsLocal = "yes" - } if defaultACL { network.DefaultACL = "yes" } @@ -63,7 +60,6 @@ func init() { networkUpdateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network") networkUpdateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network") networkUpdateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?") - networkUpdateCmd.Flags().BoolVar(&localNetwork, "local", false, "Is the network local (LAN) ?") networkUpdateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?") networkUpdateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface") networkUpdateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients") diff --git a/cli/samples/network.json b/cli/samples/network.json index d939fcd4..6de137cf 100644 --- a/cli/samples/network.json +++ b/cli/samples/network.json @@ -10,11 +10,9 @@ "defaultinterface": "nm-test3", "accesskeys": [], "allowmanualsignup": "no", - "islocal": "no", "isipv4": "yes", "isipv6": "no", "ispointtosite": "no", - "localrange": "", "defaultudpholepunch": "yes", "defaultextclientdns": "", "defaultmtu": 1280, diff --git a/cli/samples/node.json b/cli/samples/node.json index 6c7c4bd8..cacc51d0 100644 --- a/cli/samples/node.json +++ b/cli/samples/node.json @@ -18,11 +18,9 @@ "defaultkeepalive": 20, "accesskeys": [], "allowmanualsignup": "no", - "islocal": "no", "isipv4": "no", "isipv6": "yes", "ispointtosite": "no", - "localrange": "", "defaultudpholepunch": "yes", "defaultextclientdns": "", "defaultmtu": 1280, @@ -82,8 +80,6 @@ "dnson": "no", "isserver": "yes", "action": "noop", - "islocal": "no", - "localrange": "", "ipforwarding": "yes", "os": "linux", "mtu": 1280, diff --git a/models/api_node.go b/models/api_node.go index 84101267..8ff6057e 100644 --- a/models/api_node.go +++ b/models/api_node.go @@ -32,7 +32,6 @@ type ApiNode struct { RelayAddrs []string `json:"relayaddrs"` FailoverNode string `json:"failovernode"` DNSOn bool `json:"dnson"` - IsLocal bool `json:"islocal"` Server string `json:"server"` InternetGateway string `json:"internetgateway"` Connected bool `json:"connected"` @@ -51,7 +50,6 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node { convertedNode.Connected = a.Connected convertedNode.ID, _ = uuid.Parse(a.ID) convertedNode.HostID, _ = uuid.Parse(a.HostID) - convertedNode.IsLocal = a.IsLocal convertedNode.IsRelay = a.IsRelay convertedNode.IsRelayed = a.IsRelayed convertedNode.PendingDelete = a.PendingDelete @@ -150,7 +148,6 @@ func (nm *Node) ConvertToAPINode() *ApiNode { apiNode.FailoverNode = "" } apiNode.DNSOn = nm.DNSOn - apiNode.IsLocal = nm.IsLocal apiNode.Server = nm.Server apiNode.InternetGateway = nm.InternetGateway.String() if isEmptyAddr(apiNode.InternetGateway) { diff --git a/models/network.go b/models/network.go index a698e502..636e5355 100644 --- a/models/network.go +++ b/models/network.go @@ -21,7 +21,6 @@ type Network struct { DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"` AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"` AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"` - IsLocal string `json:"islocal" bson:"islocal" validate:"checkyesorno"` IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"` IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"` DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"` @@ -51,9 +50,6 @@ func (network *Network) SetDefaults() { if network.DefaultUDPHolePunch == "" { network.DefaultUDPHolePunch = "no" } - if network.IsLocal == "" { - network.IsLocal = "no" - } if network.DefaultInterface == "" { if len(network.NetID) < 13 { network.DefaultInterface = "nm-" + network.NetID diff --git a/models/node.go b/models/node.go index fb3a0b70..945323c7 100644 --- a/models/node.go +++ b/models/node.go @@ -68,7 +68,6 @@ type CommonNode struct { Address6 net.IPNet `json:"address6" yaml:"address6"` Action string `json:"action" yaml:"action"` LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"` - IsLocal bool `json:"islocal" yaml:"islocal"` IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` @@ -145,7 +144,6 @@ type LegacyNode struct { DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"` IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` Action string `json:"action" bson:"action" yaml:"action"` - IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"` IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"` OS string `json:"os" bson:"os" yaml:"os"` MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"` @@ -295,13 +293,6 @@ func (node *LegacyNode) SetIPForwardingDefault() { } } -// Node.SetIsLocalDefault - set is local default -func (node *LegacyNode) SetIsLocalDefault() { - if node.IsLocal == "" { - node.IsLocal = "no" - } -} - // Node.SetDNSOnDefault - sets dns on default func (node *LegacyNode) SetDNSOnDefault() { if node.DNSOn == "" { @@ -408,9 +399,6 @@ func (newNode *Node) Fill(currentNode *Node) { // TODO add new field for nftable if newNode.DNSOn != currentNode.DNSOn { newNode.DNSOn = currentNode.DNSOn } - if newNode.IsLocal != currentNode.IsLocal { - newNode.IsLocal = currentNode.IsLocal - } if newNode.Action == "" { newNode.Action = currentNode.Action } @@ -526,7 +514,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) { } } node.Action = ln.Action - node.IsLocal = parseBool(ln.IsLocal) node.IsEgressGateway = parseBool(ln.IsEgressGateway) node.IsIngressGateway = parseBool(ln.IsIngressGateway) node.DNSOn = parseBool(ln.DNSOn) @@ -574,7 +561,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode { l.UDPHolePunch = formatBool(true) l.DNSOn = formatBool(n.DNSOn) l.Action = n.Action - l.IsLocal = formatBool(n.IsLocal) l.IPForwarding = formatBool(h.IPForwarding) l.OS = h.OS l.MTU = int32(h.MTU) diff --git a/netclient/global_settings/globalsettings.go b/netclient/global_settings/globalsettings.go deleted file mode 100644 index 086c952b..00000000 --- a/netclient/global_settings/globalsettings.go +++ /dev/null @@ -1,9 +0,0 @@ -package global_settings - -// globalsettings - settings that are global in nature. Avoids circular dependencies between config loading and usage. - -// PublicIPServices - the list of user-specified IP services to use to obtain the node's public IP -var PublicIPServices map[string]string = make(map[string]string) - -// User - holds a user string for joins when using basic auth -var User string diff --git a/netclient/ncutils/iface.go b/netclient/ncutils/iface.go index 21665dd7..2dd4b179 100644 --- a/netclient/ncutils/iface.go +++ b/netclient/ncutils/iface.go @@ -2,62 +2,8 @@ package ncutils import ( "net" - - "github.com/gravitl/netmaker/models" ) -// IfaceDelta - checks if the new node causes an interface change -func IfaceDelta(currentNode *models.LegacyNode, newNode *models.LegacyNode) bool { - // single comparison statements - if newNode.Endpoint != currentNode.Endpoint || - newNode.PublicKey != currentNode.PublicKey || - newNode.Address != currentNode.Address || - newNode.Address6 != currentNode.Address6 || - newNode.IsEgressGateway != currentNode.IsEgressGateway || - newNode.IsIngressGateway != currentNode.IsIngressGateway || - newNode.IsRelay != currentNode.IsRelay || - newNode.ListenPort != currentNode.ListenPort || - newNode.UDPHolePunch != currentNode.UDPHolePunch || - newNode.MTU != currentNode.MTU || - newNode.IsPending != currentNode.IsPending || - newNode.PersistentKeepalive != currentNode.PersistentKeepalive || - newNode.DNSOn != currentNode.DNSOn || - newNode.Connected != currentNode.Connected || - len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) { - return true - } - - // multi-comparison statements - if newNode.IsEgressGateway == "yes" { - if len(currentNode.EgressGatewayRanges) != len(newNode.EgressGatewayRanges) { - return true - } - for _, address := range newNode.EgressGatewayRanges { - if !StringSliceContains(currentNode.EgressGatewayRanges, address) { - return true - } - } - } - - if newNode.IsRelay == "yes" { - if len(currentNode.RelayAddrs) != len(newNode.RelayAddrs) { - return true - } - for _, address := range newNode.RelayAddrs { - if !StringSliceContains(currentNode.RelayAddrs, address) { - return true - } - } - } - - for _, address := range newNode.AllowedIPs { - if !StringSliceContains(currentNode.AllowedIPs, address) { - return true - } - } - return false -} - // StringSliceContains - sees if a string slice contains a string element func StringSliceContains(slice []string, item string) bool { for _, s := range slice { @@ -68,30 +14,6 @@ func StringSliceContains(slice []string, item string) bool { return false } -// IPNetSliceContains - sees if a string slice contains a string element -func IPNetSliceContains(slice []net.IPNet, item net.IPNet) bool { - for _, s := range slice { - if s.String() == item.String() { - return true - } - } - return false -} - -// IfaceExists - return true if you can find the iface -func IfaceExists(ifacename string) bool { - localnets, err := net.Interfaces() - if err != nil { - return false - } - for _, localnet := range localnets { - if ifacename == localnet.Name { - return true - } - } - return false -} - func IpIsPrivate(ipnet net.IP) bool { return ipnet.IsPrivate() || ipnet.IsLoopback() } diff --git a/netclient/ncutils/netclientutils.go b/netclient/ncutils/netclientutils.go index e1f5ac6d..66f27e02 100644 --- a/netclient/ncutils/netclientutils.go +++ b/netclient/ncutils/netclientutils.go @@ -4,562 +4,13 @@ import ( "bytes" "crypto/rand" "encoding/gob" - "errors" - "fmt" - "io" - "log" - "net" - "net/http" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - "time" - - "github.com/c-robinson/iplib" - - "github.com/gravitl/netmaker/logger" - "github.com/gravitl/netmaker/models" - "github.com/gravitl/netmaker/netclient/global_settings" ) -var ( - // Version - version of the netclient - Version = "dev" -) - -// MAX_NAME_LENGTH - maximum node name length -const MAX_NAME_LENGTH = 62 - -// NO_DB_RECORD - error message result -const NO_DB_RECORD = "no result found" - -// NO_DB_RECORDS - error record result -const NO_DB_RECORDS = "could not find any records" - -// LINUX_APP_DATA_PATH - linux path -const LINUX_APP_DATA_PATH = "/etc/netclient" - -// MAC_APP_DATA_PATH - mac path -const MAC_APP_DATA_PATH = "/Applications/Netclient" - -// WINDOWS_APP_DATA_PATH - windows path -const WINDOWS_APP_DATA_PATH = "C:\\Program Files (x86)\\Netclient" - -// WINDOWS_SVC_NAME - service name -const WINDOWS_SVC_NAME = "netclient" - -// NETCLIENT_DEFAULT_PORT - default port -const NETCLIENT_DEFAULT_PORT = 51821 - // DEFAULT_GC_PERCENT - garbage collection percent const DEFAULT_GC_PERCENT = 10 -// KEY_SIZE = ideal length for keys -const KEY_SIZE = 2048 - -// SetVersion -- set netclient version for use by other packages -func SetVersion(ver string) { - Version = ver -} - -// IsWindows - checks if is windows -func IsWindows() bool { - return runtime.GOOS == "windows" -} - -// IsMac - checks if is a mac -func IsMac() bool { - return runtime.GOOS == "darwin" -} - -// IsLinux - checks if is linux -func IsLinux() bool { - return runtime.GOOS == "linux" -} - -// IsFreeBSD - checks if is freebsd -func IsFreeBSD() bool { - return runtime.GOOS == "freebsd" -} - -// HasWGQuick - checks if WGQuick command is present -func HasWgQuick() bool { - cmd, err := exec.LookPath("wg-quick") - return err == nil && cmd != "" -} - -// GetWireGuard - checks if wg is installed -func GetWireGuard() string { - userspace := os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION") - if userspace != "" && (userspace == "boringtun" || userspace == "wireguard-go") { - return userspace - } - return "wg" -} - -// IsNFTablesPresent - returns true if nftables is present, false otherwise. -// Does not consider OS, up to the caller to determine if the OS supports nftables/whether this check is valid. -func IsNFTablesPresent() bool { - found := false - _, err := exec.LookPath("nft") - if err == nil { - found = true - } - return found -} - -// IsIPTablesPresent - returns true if iptables is present, false otherwise -// Does not consider OS, up to the caller to determine if the OS supports iptables/whether this check is valid. -func IsIPTablesPresent() bool { - found := false - _, err := exec.LookPath("iptables") - if err == nil { - found = true - } - return found -} - -// IsKernel - checks if running kernel WireGuard -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() && os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION") == "" -} - -// IsEmptyRecord - repeat from database -func IsEmptyRecord(err error) bool { - if err == nil { - return false - } - return strings.Contains(err.Error(), NO_DB_RECORD) || strings.Contains(err.Error(), NO_DB_RECORDS) -} - -// GetPublicIP - gets public ip -func GetPublicIP(api string) (string, error) { - - iplist := []string{"https://ip.client.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"} - - for network, ipService := range global_settings.PublicIPServices { - logger.Log(3, "User provided public IP service defined for network", network, "is", ipService) - - // prepend the user-specified service so it's checked first - iplist = append([]string{ipService}, iplist...) - } - if api != "" { - api = "https://" + api + "/api/getip" - iplist = append([]string{api}, iplist...) - } - - endpoint := "" - var err error - for _, ipserver := range iplist { - client := &http.Client{ - Timeout: time.Second * 10, - } - var resp *http.Response - resp, err = client.Get(ipserver) - if err != nil { - continue - } - if resp.StatusCode == http.StatusOK { - var bodyBytes []byte - bodyBytes, err = io.ReadAll(resp.Body) - if err != nil { - if resp.Body != nil { - _ = resp.Body.Close() - } - continue - } - _ = resp.Body.Close() - endpoint = string(bodyBytes) - break - } - } - if err == nil && endpoint == "" { - err = errors.New("public address not found") - } - return endpoint, err -} - -// GetMacAddr - get's mac address -func GetMacAddr() ([]string, error) { - ifas, err := net.Interfaces() - if err != nil { - return nil, err - } - var as []string - for _, ifa := range ifas { - a := ifa.HardwareAddr.String() - if a != "" { - as = append(as, a) - } - } - return as, nil -} - -// GetLocalIP - gets local ip of machine -func GetLocalIP(localrange string) (string, error) { - _, localRange, err := net.ParseCIDR(localrange) - if err != nil { - return "", err - } - ifaces, err := net.Interfaces() - if err != nil { - return "", err - } - var local string - found := false - for _, i := range ifaces { - if i.Flags&net.FlagUp == 0 { - continue // interface down - } - if i.Flags&net.FlagLoopback != 0 { - continue // loopback interface - } - addrs, err := i.Addrs() - if err != nil { - return "", err - } - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - if !found { - ip = v.IP - local = ip.String() - found = localRange.Contains(ip) - } - case *net.IPAddr: - if !found { - ip = v.IP - local = ip.String() - found = localRange.Contains(ip) - } - } - } - } - if !found || local == "" { - return "", errors.New("Failed to find local IP in range " + localrange) - } - return local, nil -} - -// GetNetworkIPMask - Pulls the netmask out of the network -func GetNetworkIPMask(networkstring string) (string, string, error) { - ip, ipnet, err := net.ParseCIDR(networkstring) - if err != nil { - return "", "", err - } - ipstring := ip.String() - mask := ipnet.Mask - maskstring := fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]) - // maskstring := ipnet.Mask.String() - return ipstring, maskstring, err -} - -// GetFreePort - gets free port of machine -func GetFreePort(rangestart int32) (int32, error) { - addr := net.UDPAddr{} - if rangestart == 0 { - rangestart = NETCLIENT_DEFAULT_PORT - } - for x := rangestart; x <= 65535; x++ { - addr.Port = int(x) - conn, err := net.ListenUDP("udp", &addr) - if err != nil { - continue - } - defer conn.Close() - return x, nil - } - return rangestart, errors.New("no free ports") -} - // == OS PATH FUNCTIONS == -// GetHomeDirWindows - gets home directory in windows -func GetHomeDirWindows() string { - if IsWindows() { - home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") - if home == "" { - home = os.Getenv("USERPROFILE") - } - return home - } - return os.Getenv("HOME") -} - -// GetNetclientPath - gets netclient path locally -func GetNetclientPath() string { - if IsWindows() { - return WINDOWS_APP_DATA_PATH - } else if IsMac() { - return MAC_APP_DATA_PATH - } else { - return LINUX_APP_DATA_PATH - } -} - -// GetSeparator - gets the separator for OS -func GetSeparator() string { - if IsWindows() { - return "\\" - } else { - return "/" - } -} - -// GetFileWithRetry - retry getting file X number of times before failing -func GetFileWithRetry(path string, retryCount int) ([]byte, error) { - var data []byte - var err error - for count := 0; count < retryCount; count++ { - data, err = os.ReadFile(path) - if err == nil { - return data, err - } else { - logger.Log(1, "failed to retrieve file ", path, ", retrying...") - time.Sleep(time.Second >> 2) - } - } - return data, err -} - -// GetNetclientServerPath - gets netclient server path -func GetNetclientServerPath(server string) string { - if IsWindows() { - return WINDOWS_APP_DATA_PATH + "\\" + server + "\\" - } else if IsMac() { - return MAC_APP_DATA_PATH + "/" + server + "/" - } else { - return LINUX_APP_DATA_PATH + "/" + server - } -} - -// GetNetclientPathSpecific - gets specific netclient config path -func GetNetclientPathSpecific() string { - if IsWindows() { - return WINDOWS_APP_DATA_PATH + "\\" - } else if IsMac() { - return MAC_APP_DATA_PATH + "/config/" - } else { - return LINUX_APP_DATA_PATH + "/config/" - } -} - -func CheckIPAddress(ip string) error { - if net.ParseIP(ip) == nil { - return fmt.Errorf("ip address %s is invalid", ip) - } - return nil -} - -// GetNewIface - Gets the name of the real interface created on Mac -func GetNewIface(dir string) (string, error) { - files, _ := os.ReadDir(dir) - var newestFile string - var newestTime int64 = 0 - var err error - for _, f := range files { - fi, err := os.Stat(dir + f.Name()) - if err != nil { - return "", err - } - currTime := fi.ModTime().Unix() - if currTime > newestTime && strings.Contains(f.Name(), ".sock") { - newestTime = currTime - newestFile = f.Name() - } - } - resultArr := strings.Split(newestFile, ".") - if resultArr[0] == "" { - err = errors.New("sock file does not exist") - } - return resultArr[0], err -} - -// GetFileAsString - returns the string contents of a given file -func GetFileAsString(path string) (string, error) { - content, err := os.ReadFile(path) - if err != nil { - return "", err - } - return string(content), err -} - -// GetNetclientPathSpecific - gets specific netclient config path -func GetWGPathSpecific() string { - if IsWindows() { - return WINDOWS_APP_DATA_PATH + "\\" - } else { - return "/etc/wireguard/" - } -} - -// Copy - copies a src file to dest -func Copy(src, dst string) error { - sourceFileStat, err := os.Stat(src) - if err != nil { - return err - } - - if !sourceFileStat.Mode().IsRegular() { - return errors.New(src + " is not a regular file") - } - - source, err := os.Open(src) - if err != nil { - return err - } - defer source.Close() - - destination, err := os.Create(dst) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err - } - err = os.Chmod(dst, 0755) - - return err -} - -// RunsCmds - runs cmds -func RunCmds(commands []string, printerr bool) error { - var err error - for _, command := range commands { - // prevent panic - if len(strings.Trim(command, " ")) == 0 { - continue - } - args := strings.Fields(command) - out, err := exec.Command(args[0], args[1:]...).CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command:", command) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - } - return err -} - -// FileExists - checks if file exists locally -func FileExists(f string) bool { - info, err := os.Stat(f) - if os.IsNotExist(err) { - return false - } - if err != nil && strings.Contains(err.Error(), "not a directory") { - return false - } - if err != nil { - logger.Log(0, "error reading file: "+f+", "+err.Error()) - } - return !info.IsDir() -} - -// GetSystemNetworks - get networks locally -func GetSystemNetworks() ([]string, error) { - var networks []string - files, err := filepath.Glob(GetNetclientPathSpecific() + "netconfig-*") - if err != nil { - return nil, err - } - for _, file := range files { - // don't want files such as *.bak, *.swp - if filepath.Ext(file) != "" { - continue - } - file := filepath.Base(file) - temp := strings.Split(file, "-") - networks = append(networks, strings.Join(temp[1:], "-")) - } - return networks, nil -} - -// ShortenString - Brings string down to specified length. Stops names from being too long -func ShortenString(input string, length int) string { - output := input - if len(input) > length { - output = input[0:length] - } - return output -} - -// DNSFormatString - Formats a string with correct usage for DNS -func DNSFormatString(input string) string { - reg, err := regexp.Compile("[^a-zA-Z0-9-]+") - if err != nil { - logger.Log(0, "error with regex: "+err.Error()) - return "" - } - return reg.ReplaceAllString(input, "") -} - -// GetHostname - Gets hostname of machine -func GetHostname() string { - hostname, err := os.Hostname() - if err != nil { - return "" - } - if len(hostname) > MAX_NAME_LENGTH { - hostname = hostname[0:MAX_NAME_LENGTH] - } - return hostname -} - -// CheckUID - Checks to make sure user has root privileges -func CheckUID() { - // start our application - out, err := RunCmd("id -u", true) - - if err != nil { - log.Fatal(out, err) - } - id, err := strconv.Atoi(string(out[:len(out)-1])) - - if err != nil { - log.Fatal(err) - } - - if id != 0 { - log.Fatal("This program must be run with elevated privileges (sudo). This program installs a SystemD service and configures WireGuard and networking rules. Please re-run with sudo/root.") - } -} - -// CheckFirewall - checks if iptables of nft install, if not exit -func CheckFirewall() { - if !IsIPTablesPresent() && !IsNFTablesPresent() { - log.Fatal("neither iptables nor nft is installed - please install one or the other and try again") - } -} - -// CheckWG - Checks if WireGuard is installed. If not, exit -func CheckWG() { - uspace := GetWireGuard() - if !HasWG() { - if uspace == "wg" { - log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.") - } - logger.Log(0, "running with userspace wireguard: ", uspace) - } else if uspace != "wg" { - logger.Log(0, "running userspace WireGuard with ", uspace) - } -} - -// HasWG - returns true if wg command exists -func HasWG() bool { - var _, err = exec.LookPath("wg") - return err == nil -} - // ConvertKeyToBytes - util to convert a key to bytes to use elsewhere func ConvertKeyToBytes(key *[32]byte) ([]byte, error) { var buffer bytes.Buffer @@ -582,16 +33,6 @@ func ConvertBytesToKey(data []byte) (*[32]byte, error) { return result, err } -// ServerAddrSliceContains - sees if a string slice contains a string element -func ServerAddrSliceContains(slice []models.ServerAddr, item models.ServerAddr) bool { - for _, s := range slice { - if s.Address == item.Address && s.IsLeader == item.IsLeader { - return true - } - } - return false -} - // MakeRandomString - generates a random string of len n func MakeRandomString(n int) string { const validChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -604,40 +45,3 @@ func MakeRandomString(n int) string { } return string(result) } - -func GetIPNetFromString(ip string) (net.IPNet, error) { - var ipnet *net.IPNet - var err error - // parsing as a CIDR first. If valid CIDR, append - if _, cidr, err := net.ParseCIDR(ip); err == nil { - ipnet = cidr - } else { // parsing as an IP second. If valid IP, check if ipv4 or ipv6, then append - if iplib.Version(net.ParseIP(ip)) == 4 { - ipnet = &net.IPNet{ - IP: net.ParseIP(ip), - Mask: net.CIDRMask(32, 32), - } - } else if iplib.Version(net.ParseIP(ip)) == 6 { - ipnet = &net.IPNet{ - IP: net.ParseIP(ip), - Mask: net.CIDRMask(128, 128), - } - } - } - if ipnet == nil { - err = errors.New(ip + " is not a valid ip or cidr") - return net.IPNet{}, err - } - return *ipnet, err -} - -// ModPort - Change Node Port if UDP Hole Punching or ListenPort is not free -func ModPort(node *models.LegacyNode) error { - var err error - if node.UDPHolePunch == "yes" { - node.ListenPort = 0 - } else { - node.ListenPort, err = GetFreePort(node.ListenPort) - } - return err -} diff --git a/netclient/ncutils/netclientutils_darwin.go b/netclient/ncutils/netclientutils_darwin.go deleted file mode 100644 index 157a58fc..00000000 --- a/netclient/ncutils/netclientutils_darwin.go +++ /dev/null @@ -1,39 +0,0 @@ -package ncutils - -import ( - "os/exec" - "strings" - - "github.com/gravitl/netmaker/logger" -) - -// WHITESPACE_PLACEHOLDER - used with RunCMD - if a path has whitespace, use this to avoid running path as 2 args in RunCMD -const WHITESPACE_PLACEHOLDER = "+-+-+-+" - -// RunCmd - runs a local command -func RunCmd(command string, printerr bool) (string, error) { - - args := strings.Fields(command) - // return whitespace after split - for i, arg := range args { - args[i] = strings.Replace(arg, WHITESPACE_PLACEHOLDER, " ", -1) - } - cmd := exec.Command(args[0], args[1:]...) - cmd.Wait() - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command:", strings.Join(args, " ")) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} - -// RunCmdFormatted - run a command formatted for MacOS -func RunCmdFormatted(command string, printerr bool) (string, error) { - return "", nil -} - -// GetEmbedded - if files required for MacOS, put here -func GetEmbedded() error { - return nil -} diff --git a/netclient/ncutils/netclientutils_freebsd.go b/netclient/ncutils/netclientutils_freebsd.go deleted file mode 100644 index 6a976d04..00000000 --- a/netclient/ncutils/netclientutils_freebsd.go +++ /dev/null @@ -1,50 +0,0 @@ -package ncutils - -import ( - "context" - "os/exec" - "strings" - "syscall" - "time" - - "github.com/gravitl/netmaker/logger" -) - -// RunCmdFormatted - run a command formatted for freebsd -func RunCmdFormatted(command string, printerr bool) (string, error) { - - args := strings.Fields(command) - cmd := exec.Command(args[0], args[1:]...) - cmd.Start() - cmd.Wait() - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command: ", command) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} - -// GetEmbedded - if files required for freebsd, put here -func GetEmbedded() error { - return nil -} - -// Runs Commands for FreeBSD -func RunCmd(command string, printerr bool) (string, error) { - args := strings.Fields(command) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - cmd := exec.Command(args[0], args[1:]...) - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} - go func() { - <-ctx.Done() - _ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) - }() - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command:", command) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} diff --git a/netclient/ncutils/netclientutils_linux.go b/netclient/ncutils/netclientutils_linux.go deleted file mode 100644 index 76c1da1d..00000000 --- a/netclient/ncutils/netclientutils_linux.go +++ /dev/null @@ -1,32 +0,0 @@ -package ncutils - -import ( - "fmt" - "os/exec" - "strings" - - "github.com/gravitl/netmaker/logger" -) - -// RunCmd - runs a local command -func RunCmd(command string, printerr bool) (string, error) { - args := strings.Fields(command) - cmd := exec.Command(args[0], args[1:]...) - cmd.Wait() - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, fmt.Sprintf("error running command: %s", command)) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} - -// RunCmdFormatted - does nothing for linux -func RunCmdFormatted(command string, printerr bool) (string, error) { - return "", nil -} - -// GetEmbedded - if files required for linux, put here -func GetEmbedded() error { - return nil -} diff --git a/netclient/ncutils/netclientutils_windows.go b/netclient/ncutils/netclientutils_windows.go deleted file mode 100644 index 6f85ab0c..00000000 --- a/netclient/ncutils/netclientutils_windows.go +++ /dev/null @@ -1,61 +0,0 @@ -package ncutils - -import ( - "embed" - "fmt" - "os" - "os/exec" - "strings" - "syscall" - - "github.com/gravitl/netmaker/logger" -) - -//go:embed windowsdaemon/winsw.exe -var winswContent embed.FS - -// RunCmd - runs a local command -func RunCmd(command string, printerr bool) (string, error) { - args := strings.Fields(command) - cmd := exec.Command(args[0], args[1:]...) - cmd.Wait() - //cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/C \"" + command + "\""} - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command:", command) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} - -// RunCmd - runs a local command -func RunCmdFormatted(command string, printerr bool) (string, error) { - var comSpec = os.Getenv("COMSPEC") - if comSpec == "" { - comSpec = os.Getenv("SystemRoot") + "\\System32\\cmd.exe" - } - cmd := exec.Command(comSpec) - cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/C \"" + command + "\""} - cmd.Wait() - out, err := cmd.CombinedOutput() - if err != nil && printerr { - logger.Log(0, "error running command:", command) - logger.Log(0, strings.TrimSuffix(string(out), "\n")) - } - return string(out), err -} - -// GetEmbedded - Gets the Windows daemon creator -func GetEmbedded() error { - data, err := winswContent.ReadFile("windowsdaemon/winsw.exe") - if err != nil { - return err - } - fileName := fmt.Sprintf("%swinsw.exe", GetNetclientPathSpecific()) - err = os.WriteFile(fileName, data, 0700) - if err != nil { - logger.Log(0, "could not mount winsw.exe") - return err - } - return nil -} diff --git a/netclient/ncutils/peerhelper.go b/netclient/ncutils/peerhelper.go deleted file mode 100644 index fd0c9da3..00000000 --- a/netclient/ncutils/peerhelper.go +++ /dev/null @@ -1,97 +0,0 @@ -package ncutils - -import ( - "net" - "strconv" - "strings" - "time" - - "github.com/gravitl/netmaker/logger" - "golang.zx2c4.com/wireguard/wgctrl/wgtypes" -) - -// GetPeers - gets the peers from a given WireGuard interface -func GetPeers(iface string) ([]wgtypes.Peer, error) { - - var peers []wgtypes.Peer - output, err := RunCmd("wg show "+iface+" dump", true) - if err != nil { - return peers, err - } - for i, line := range strings.Split(strings.TrimSuffix(output, "\n"), "\n") { - if i == 0 { - continue - } - var allowedIPs []net.IPNet - fields := strings.Fields(line) - if len(fields) < 4 { - logger.Log(0, "error parsing peer: "+line) - continue - } - pubkeystring := fields[0] - endpointstring := fields[2] - allowedipstring := fields[3] - var pkeepalivestring string - if len(fields) > 7 { - pkeepalivestring = fields[7] - } - // AllowedIPs = private IP + defined networks - - pubkey, err := wgtypes.ParseKey(pubkeystring) - if err != nil { - logger.Log(0, "error parsing peer key "+pubkeystring) - continue - } - ipstrings := strings.Split(allowedipstring, ",") - for _, ipstring := range ipstrings { - var netip net.IP - if netip = net.ParseIP(strings.Split(ipstring, "/")[0]); netip != nil { - allowedIPs = append( - allowedIPs, - net.IPNet{ - IP: netip, - Mask: netip.DefaultMask(), - }, - ) - } - } - if len(allowedIPs) == 0 { - logger.Log(0, "error parsing peer "+pubkeystring+", no allowedips found") - continue - } - var endpointarr []string - var endpointip net.IP - if endpointarr = strings.Split(endpointstring, ":"); len(endpointarr) != 2 { - logger.Log(0, "error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointstring) - continue - } - if endpointip = net.ParseIP(endpointarr[0]); endpointip == nil { - logger.Log(0, "error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointarr[0]) - continue - } - var port int - if port, err = strconv.Atoi(endpointarr[1]); err != nil { - logger.Log(0, "error parsing peer "+pubkeystring+", could not parse port: "+err.Error()) - continue - } - var endpoint = net.UDPAddr{ - IP: endpointip, - Port: port, - } - var dur time.Duration - if pkeepalivestring != "" { - if dur, err = time.ParseDuration(pkeepalivestring + "s"); err != nil { - logger.Log(0, "error parsing peer "+pubkeystring+", could not parse keepalive: "+err.Error()) - } - } - - peers = append(peers, wgtypes.Peer{ - PublicKey: pubkey, - Endpoint: &endpoint, - AllowedIPs: allowedIPs, - PersistentKeepaliveInterval: dur, - }) - } - - return peers, err -} diff --git a/netclient/ncutils/pid.go b/netclient/ncutils/pid.go deleted file mode 100644 index 88491aa0..00000000 --- a/netclient/ncutils/pid.go +++ /dev/null @@ -1,46 +0,0 @@ -package ncutils - -import ( - "fmt" - "os" - "strconv" -) - -// PIDFILE - path/name of pid file -const PIDFILE = "/var/run/netclient.pid" - -// WindowsPIDError - error returned from pid function on windows -type WindowsPIDError struct{} - -// Error generates error for windows os -func (*WindowsPIDError) Error() string { - return "pid tracking not supported on windows" -} - -// SavePID - saves the pid of running program to disk -func SavePID() error { - if IsWindows() { - return nil - } - pid := os.Getpid() - if err := os.WriteFile(PIDFILE, []byte(fmt.Sprintf("%d", pid)), 0644); err != nil { - return fmt.Errorf("could not write to pid file %w", err) - } - return nil -} - -// ReadPID - reads a previously saved pid from disk -func ReadPID() (int, error) { - if IsWindows() { - return 0, nil - } - bytes, err := os.ReadFile(PIDFILE) - if err != nil { - return 0, fmt.Errorf("could not read pid file %w", err) - } - pid, err := strconv.Atoi(string(bytes)) - if err != nil { - return 0, fmt.Errorf("pid file contents invalid %w", err) - } - return pid, nil -} diff --git a/netclient/ncutils/util.go b/netclient/ncutils/util.go index d7df17b0..aa2ce510 100644 --- a/netclient/ncutils/util.go +++ b/netclient/ncutils/util.go @@ -1,29 +1,4 @@ package ncutils -import ( - "fmt" - "time" - - "github.com/gravitl/netmaker/logger" -) - // CheckInInterval - the interval for check-in time in units/minute const CheckInInterval = 1 - -// BackOff - back off any function while there is an error -func BackOff(isExponential bool, maxTime int, f interface{}) (interface{}, error) { - // maxTime seconds - startTime := time.Now() - sleepTime := time.Second - for time.Now().Before(startTime.Add(time.Second * time.Duration(maxTime))) { - if result, err := f.(func() (interface{}, error))(); err == nil { - return result, nil - } - time.Sleep(sleepTime) - if isExponential { - sleepTime = sleepTime << 1 - } - logger.Log(1, "retrying...") - } - return nil, fmt.Errorf("could not find result") -} diff --git a/netclient/ncutils/windowsdaemon/winsw.exe b/netclient/ncutils/windowsdaemon/winsw.exe deleted file mode 100644 index ba27e3fd..00000000 Binary files a/netclient/ncutils/windowsdaemon/winsw.exe and /dev/null differ diff --git a/swagger.yaml b/swagger.yaml index ec498572..f1bc5518 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -273,9 +273,6 @@ definitions: isipv6: type: string x-go-name: IsIPv6 - islocal: - type: string - x-go-name: IsLocal ispointtosite: type: string x-go-name: IsPointToSite @@ -375,9 +372,6 @@ definitions: isk8s: type: string x-go-name: IsK8S - islocal: - type: string - x-go-name: IsLocal ispending: type: string x-go-name: IsPending