From 21ba362eca9d5219f7edd22bd6057d46df7f5e12 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Sat, 2 Oct 2021 12:28:17 -0400 Subject: [PATCH] allowing IsServer to be modified, configurable checkin time, single checkin for linux, moved cfg files --- config/config.go | 1 + controllers/common.go | 4 +-- controllers/networkHttpController.go | 1 + functions/helpers.go | 1 + models/accessToken.go | 1 + models/network.go | 2 ++ models/node.go | 5 ++- netclient/command/commands.go | 24 +++++++++++-- netclient/config/config.go | 19 +++++++--- netclient/daemon/common.go | 10 ++++-- netclient/daemon/macos.go | 17 ++++----- netclient/daemon/systemd.go | 52 +++++++++++++--------------- netclient/functions/common.go | 2 +- netclient/local/local.go | 5 --- netclient/main.go | 1 + netclient/ncutils/netclientutils.go | 5 +-- servercfg/serverconf.go | 11 ++++++ 17 files changed, 105 insertions(+), 56 deletions(-) diff --git a/config/config.go b/config/config.go index 1c2c4810..1e2ed656 100644 --- a/config/config.go +++ b/config/config.go @@ -56,6 +56,7 @@ type ServerConfig struct { SQLConn string `yaml:"sqlconn"` Platform string `yaml:"platform"` Database string `yaml:database` + CheckinInterval string `yaml:checkininterval` DefaultNodeLimit int32 `yaml:"defaultnodelimit"` Verbosity int32 `yaml:"verbosity"` } diff --git a/controllers/common.go b/controllers/common.go index a39169d0..7a07e38b 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -249,9 +249,7 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) { node.Network = networkName if node.Name == models.NODE_SERVER_NAME { - if node.CheckIsServer() { - node.IsServer = "yes" - } + node.IsServer = "yes" } if servercfg.IsDNSMode() && node.DNSOn == ""{ node.DNSOn = "yes" diff --git a/controllers/networkHttpController.go b/controllers/networkHttpController.go index 0b0df2a4..091c7d29 100644 --- a/controllers/networkHttpController.go +++ b/controllers/networkHttpController.go @@ -473,6 +473,7 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models GRPCHost: s.GRPCHost, GRPCPort: s.GRPCPort, GRPCSSL: s.GRPCSSL, + CheckinInterval: s.CheckinInterval, } accessToken.ServerConfig = servervals accessToken.ClientConfig.Network = netID diff --git a/functions/helpers.go b/functions/helpers.go index 6993eff4..d9975340 100644 --- a/functions/helpers.go +++ b/functions/helpers.go @@ -106,6 +106,7 @@ func CreateServerToken(netID string) (string, error) { APIConnString: "127.0.0.1:" + servercfg.GetAPIPort(), GRPCConnString: "127.0.0.1:" + servercfg.GetGRPCPort(), GRPCSSL: "off", + CheckinInterval: servercfg.GetCheckinInterval(), } } log.Println("APIConnString:", servervals.APIConnString) diff --git a/models/accessToken.go b/models/accessToken.go index a55524c6..1ef945d4 100644 --- a/models/accessToken.go +++ b/models/accessToken.go @@ -21,6 +21,7 @@ type ServerConfig struct { GRPCHost string `json:"grpchost"` GRPCPort string `json:"grpcport"` GRPCSSL string `json:"grpcssl"` + CheckinInterval string `json:"checkininterval"` } type WG struct { diff --git a/models/network.go b/models/network.go index c71ed15c..f08303c5 100644 --- a/models/network.go +++ b/models/network.go @@ -37,6 +37,8 @@ type Network struct { IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"` IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub" validate:"checkyesorno"` LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"` + + // checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"` DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"` DefaultExtClientDNS string `json:"defaultextclientdns" bson:"defaultextclientdns"` diff --git a/models/node.go b/models/node.go index bae420e6..f5bcb0f0 100644 --- a/models/node.go +++ b/models/node.go @@ -49,6 +49,7 @@ type Node struct { LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,mac,macaddress_unique"` + // checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL CheckInInterval int32 `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"` Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"` Network string `json:"network" bson:"network" yaml:"network" validate:"network_exists"` @@ -414,7 +415,9 @@ func (newNode *Node) Fill(currentNode *Node) { if newNode.Action == "" { newNode.Action = currentNode.Action } - newNode.IsServer = currentNode.IsServer + if newNode.IsServer == "" { + newNode.IsServer = currentNode.IsServer + } if newNode.IsServer == "yes" { newNode.IsStatic = "yes" } diff --git a/netclient/command/commands.go b/netclient/command/commands.go index 626ff288..65d6ef5f 100644 --- a/netclient/command/commands.go +++ b/netclient/command/commands.go @@ -5,7 +5,7 @@ import ( "os" "strings" "time" - + "strconv" nodepb "github.com/gravitl/netmaker/grpc" "github.com/gravitl/netmaker/netclient/config" "github.com/gravitl/netmaker/netclient/daemon" @@ -56,15 +56,35 @@ func Join(cfg config.ClientConfig, privateKey string) error { return err } +func getWindowsInterval() int { + interval := 15 + networks, err := functions.GetNetworks() + if err != nil { + return interval + } + cfg, err := config.ReadConfig(networks[0]) + if err != nil { + return interval + } + netint, err := strconv.Atoi(cfg.Server.CheckinInterval) + if err == nil && netint != 0 { + interval = netint + } + return interval +} + func RunUserspaceDaemon() { + cfg := config.ClientConfig{ Network: "all", } + interval := getWindowsInterval() + dur := time.Duration(interval) * time.Second for { if err := CheckIn(cfg); err != nil { // pass } - time.Sleep(15 * time.Second) + time.Sleep(dur) } } diff --git a/netclient/config/config.go b/netclient/config/config.go index 5d5fbbce..5588e263 100644 --- a/netclient/config/config.go +++ b/netclient/config/config.go @@ -35,6 +35,7 @@ type ServerConfig struct { AccessKey string `yaml:"accesskey"` GRPCSSL string `yaml:"grpcssl"` GRPCWireGuard string `yaml:"grpcwg"` + CheckinInterval string `yaml:"checkininterval"` } //reading in the env file @@ -43,9 +44,9 @@ func Write(config *ClientConfig, network string) error { err := errors.New("no network provided - exiting") return err } - _, err := os.Stat(ncutils.GetNetclientPath()) + _, err := os.Stat(ncutils.GetNetclientPath()+"/config") if os.IsNotExist(err) { - os.Mkdir(ncutils.GetNetclientPath(), 0744) + os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744) } else if err != nil { return err } @@ -72,9 +73,9 @@ func WriteServer(server string, accesskey string, network string) error { } nofile := false //home, err := homedir.Dir() - _, err := os.Stat(ncutils.GetNetclientPath()) + _, err := os.Stat(ncutils.GetNetclientPath()+"/config") if os.IsNotExist(err) { - os.Mkdir(ncutils.GetNetclientPath(), 0744) + os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744) } else if err != nil { fmt.Println("couldnt find or create", ncutils.GetNetclientPath()) return err @@ -230,11 +231,13 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) { cfg.Server.GRPCAddress = cfg.Server.GRPCAddress + ":" + accesstoken.ServerConfig.GRPCPort } } + cfg.Network = accesstoken.ClientConfig.Network cfg.Node.Network = accesstoken.ClientConfig.Network cfg.Server.AccessKey = accesstoken.ClientConfig.Key cfg.Node.LocalRange = accesstoken.ClientConfig.LocalRange cfg.Server.GRPCSSL = accesstoken.ServerConfig.GRPCSSL + cfg.Server.CheckinInterval = accesstoken.ServerConfig.CheckinInterval cfg.Server.GRPCWireGuard = accesstoken.WG.GRPCWireGuard cfg.Server.CoreDNSAddr = accesstoken.ServerConfig.CoreDNSAddr if c.String("grpcserver") != "" { @@ -262,6 +265,9 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) { if c.String("grpcwg") != "" { cfg.Server.GRPCWireGuard = c.String("grpcwg") } + if c.String("checkininterval") != "" { + cfg.Server.CheckinInterval = c.String("checkininterval") + } } else { cfg.Server.GRPCAddress = c.String("grpcserver") @@ -273,6 +279,7 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) { cfg.Server.GRPCWireGuard = c.String("grpcwg") cfg.Server.GRPCSSL = c.String("grpcssl") cfg.Server.CoreDNSAddr = c.String("corednsaddr") + cfg.Server.CheckinInterval = c.String("checkininterval") } cfg.Node.Name = c.String("name") cfg.Node.Interface = c.String("interface") @@ -298,6 +305,10 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) { cfg.Node.UDPHolePunch = c.String("udpholepunch") cfg.Node.MTU = int32(c.Int("mtu")) + if cfg.Server.CheckinInterval == "" { + cfg.Server.CheckinInterval = "15" + } + return cfg, privateKey, nil } diff --git a/netclient/daemon/common.go b/netclient/daemon/common.go index aca982a5..a8794e55 100644 --- a/netclient/daemon/common.go +++ b/netclient/daemon/common.go @@ -10,13 +10,19 @@ import ( func InstallDaemon(cfg config.ClientConfig) error { os := runtime.GOOS var err error + + interval := "15" + if cfg.Server.CheckinInterval != "" { + interval = cfg.Server.CheckinInterval + } + switch os { case "windows": err = SetupWindowsDaemon() case "darwin": - err = SetupMacDaemon() + err = SetupMacDaemon(interval) case "linux": - err = SetupSystemDDaemon(cfg.Network) + err = SetupSystemDDaemon(interval) default: err = errors.New("this os is not yet supported for daemon mode. Run join cmd with flag '--daemon off'") } diff --git a/netclient/daemon/macos.go b/netclient/daemon/macos.go index 9e50a260..86d1ba8c 100644 --- a/netclient/daemon/macos.go +++ b/netclient/daemon/macos.go @@ -4,13 +4,14 @@ import ( "io/ioutil" "log" "os" + "fmt" "path/filepath" "github.com/gravitl/netmaker/netclient/ncutils" ) const MAC_SERVICE_NAME = "com.gravitl.netclient" -func SetupMacDaemon() error { +func SetupMacDaemon(interval string) error { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { @@ -30,7 +31,7 @@ func SetupMacDaemon() error { if os.IsNotExist(errN) { os.Mkdir("~/Library/LaunchAgents", 0755) } - err = CreateMacService(MAC_SERVICE_NAME) + err = CreateMacService(MAC_SERVICE_NAME, interval) if err != nil { return err } @@ -50,7 +51,7 @@ func CleanupMac() { os.RemoveAll(ncutils.GetNetclientPath()) } -func CreateMacService(servicename string) error { +func CreateMacService(servicename string, interval string) error { _, err := os.Stat("/Library/LaunchDaemons") if os.IsNotExist(err) { os.Mkdir("/Library/LaunchDaemons", 0755) @@ -58,7 +59,7 @@ func CreateMacService(servicename string) error { log.Println("couldnt find or create /Library/LaunchDaemons") return err } - daemonstring := MacDaemonString() + daemonstring := MacDaemonString(interval) daemonbytes := []byte(daemonstring) if !ncutils.FileExists("/Library/LaunchDaemons/com.gravitl.netclient.plist") { @@ -67,8 +68,8 @@ func CreateMacService(servicename string) error { return err } -func MacDaemonString() string { - return ` +func MacDaemonString(interval string) string { + return fmt.Sprintf(` @@ -84,7 +85,7 @@ func MacDaemonString() string { StandardErrorPath/etc/netclient/com.gravitl.netclient.log AbandonProcessGroup StartInterval - 15 + %s EnvironmentVariables PATH @@ -92,7 +93,7 @@ func MacDaemonString() string { -` +`,interval) } type MacTemplateData struct { diff --git a/netclient/daemon/systemd.go b/netclient/daemon/systemd.go index 27b8c7af..c2b02ee7 100644 --- a/netclient/daemon/systemd.go +++ b/netclient/daemon/systemd.go @@ -11,7 +11,8 @@ import ( "github.com/gravitl/netmaker/netclient/ncutils" ) -func SetupSystemDDaemon(network string) error { +func SetupSystemDDaemon(interval string) error { + if ncutils.IsWindows() { return nil } @@ -21,9 +22,9 @@ func SetupSystemDDaemon(network string) error { } binarypath := dir + "/netclient" - _, err = os.Stat("/etc/netclient") + _, err = os.Stat("/etc/netclient/config") if os.IsNotExist(err) { - os.Mkdir("/etc/netclient", 744) + os.MkdirAll("/etc/netclient/config", 0744) } else if err != nil { log.Println("couldnt find or create /etc/netclient") return err @@ -46,7 +47,7 @@ Wants=netclient.timer [Service] Type=simple -ExecStart=/etc/netclient/netclient checkin -n %i +ExecStart=/etc/netclient/netclient checkin -n all [Install] WantedBy=multi-user.target @@ -54,23 +55,17 @@ WantedBy=multi-user.target systemtimer := `[Unit] Description=Calls the Netmaker Mesh Client Service - -` - systemtimer = systemtimer + "Requires=netclient@" + network + ".service" - - systemtimer = systemtimer + - ` +Requires=netclient.service [Timer] +Unit=netclient.service ` - systemtimer = systemtimer + "Unit=netclient@" + network + ".service" + systemtimer = systemtimer + "OnCalendar=*:*:0/" + interval systemtimer = systemtimer + ` -OnCalendar=*:*:0/15 - [Install] WantedBy=timers.target ` @@ -78,26 +73,26 @@ 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 !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 !ncutils.FileExists("/etc/systemd/system/netclient.timer") { + err = ioutil.WriteFile("/etc/systemd/system/netclient.timer", timerbytes, 0644) if err != nil { log.Println(err) return err } } - _, _ = ncutils.RunCmd("systemctl enable netclient@.service", true) + _, _ = 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) + _, _ = ncutils.RunCmd("systemctl enable netclient.timer", true) + _, _ = ncutils.RunCmd("systemctl start netclient.timer", true) return nil } @@ -110,20 +105,20 @@ func RemoveSystemDServices(network string) error { } if fullremove { - _, err = ncutils.RunCmd("systemctl disable netclient@.service", true) + _, 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 ncutils.FileExists("/etc/systemd/system/netclient.timer") { + _, _ = ncutils.RunCmd("systemctl disable netclient.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.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 ncutils.FileExists("/etc/systemd/system/netclient.timer") { + err = os.Remove("/etc/systemd/system/netclient.timer") } if err != nil { log.Println("Error removing file. Please investigate.") @@ -135,9 +130,10 @@ func RemoveSystemDServices(network string) error { return nil } + func isOnlyService(network string) (bool, error) { isonly := false - files, err := filepath.Glob("/etc/netclient/netconfig-*") + files, err := filepath.Glob("/etc/netclient/config/netconfig-*") if err != nil { return isonly, err } diff --git a/netclient/functions/common.go b/netclient/functions/common.go index 35d54afe..4f403fcf 100644 --- a/netclient/functions/common.go +++ b/netclient/functions/common.go @@ -269,7 +269,7 @@ func List() error { func GetNetworks() ([]string, error) { var networks []string - files, err := ioutil.ReadDir(ncutils.GetNetclientPath()) + files, err := ioutil.ReadDir(ncutils.GetNetclientPathSpecific()) if err != nil { return networks, err } diff --git a/netclient/local/local.go b/netclient/local/local.go index 87efd92e..7f761d5c 100644 --- a/netclient/local/local.go +++ b/netclient/local/local.go @@ -91,10 +91,5 @@ func GetMacIface(ipstring string) (string, error) { } func HasNetwork(network string) bool { - - if ncutils.IsWindows() { return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network) - } - return ncutils.FileExists("/etc/systemd/system/netclient-"+network+".timer") || - ncutils.FileExists(ncutils.GetNetclientPathSpecific()+"netconfig-"+network) } diff --git a/netclient/main.go b/netclient/main.go index 30d1a1dc..0825dac9 100644 --- a/netclient/main.go +++ b/netclient/main.go @@ -358,6 +358,7 @@ func main() { } } if len(os.Args) == 1 && ncutils.IsWindows() { + c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { diff --git a/netclient/ncutils/netclientutils.go b/netclient/ncutils/netclientutils.go index 30e1a807..7dea5934 100644 --- a/netclient/ncutils/netclientutils.go +++ b/netclient/ncutils/netclientutils.go @@ -280,13 +280,14 @@ func GetNetclientPath() string { } } + func GetNetclientPathSpecific() string { if IsWindows() { return WINDOWS_APP_DATA_PATH + "\\" } else if IsMac() { - return "/etc/netclient/" + return "/etc/netclient/config/" } else { - return LINUX_APP_DATA_PATH + "/" + return LINUX_APP_DATA_PATH + "/config/" } } diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index b5748065..02361159 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -31,6 +31,7 @@ func GetServerConfig() config.ServerConfig { cfg.AllowedOrigin = GetAllowedOrigin() cfg.RestBackend = "off" cfg.Verbosity = GetVerbose() + cfg.CheckinInterval = GetCheckinInterval() if IsRestBackend() { cfg.RestBackend = "on" } @@ -122,6 +123,16 @@ func GetAPIPort() string { return apiport } +func GetCheckinInterval() string { + seconds := "15" + if os.Getenv("CHECKIN_INTERVAL") != "" { + seconds = os.Getenv("CHECKIN_INTERVAL") + } else if config.Config.Server.CheckinInterval != "" { + seconds = config.Config.Server.CheckinInterval + } + return seconds +} + func GetDefaultNodeLimit() int32 { var limit int32 limit = 999999999