memory issue work

This commit is contained in:
0xdcarns
2021-12-08 16:52:32 -05:00
parent 09033e1e0b
commit 85e8c0abb6
12 changed files with 445 additions and 478 deletions

View File

@@ -5,7 +5,7 @@ RUN apk add build-base
WORKDIR /app
COPY . .
ENV GO111MODULE=auto
RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -X 'main.version=$version'" -o netmaker main.go
RUN GOOS=linux CGO_ENABLED=1 go build -tags debug -ldflags="-s -X 'main.version=$version'" -o netmaker main.go
FROM alpine:3.13.6
# add a c lib
RUN apk add gcompat iptables

View File

@@ -15,6 +15,17 @@ import (
"github.com/gravitl/netmaker/servercfg"
)
var HttpHandlers = []interface{}{
nodeHandlers,
userHandlers,
networkHandlers,
dnsHandlers,
fileHandlers,
serverHandlers,
extClientHandlers,
loggerHandlers,
}
// HandleRESTRequests - handles the rest requests
func HandleRESTRequests(wg *sync.WaitGroup) {
defer wg.Done()
@@ -27,14 +38,9 @@ func HandleRESTRequests(wg *sync.WaitGroup) {
originsOk := handlers.AllowedOrigins([]string{servercfg.GetAllowedOrigin()})
methodsOk := handlers.AllowedMethods([]string{"GET", "PUT", "POST", "DELETE"})
nodeHandlers(r)
userHandlers(r)
networkHandlers(r)
dnsHandlers(r)
fileHandlers(r)
serverHandlers(r)
extClientHandlers(r)
loggerHandlers(r)
for _, handler := range HttpHandlers {
handler.(func(*mux.Router))(r)
}
port := servercfg.GetAPIPort()

33
controllers/debug.go Normal file
View File

@@ -0,0 +1,33 @@
//go:build debug
package controller
import (
"context"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"github.com/gravitl/netmaker/logger"
)
func init() {
srv := &http.Server{Addr: "0.0.0.0:6060", Handler: nil}
go func() {
logger.Log(0, "Debug mode active")
err := srv.ListenAndServe()
if err != nil {
logger.Log(0, err.Error())
}
c := make(chan os.Signal)
// Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)
// Ignore other incoming signals
signal.Notify(c, os.Interrupt)
// Block main routine until a signal is received
// As long as user doesn't press CTRL+C a message is not passed and our main routine keeps running
<-c
srv.Shutdown(context.TODO())
}()
}

View File

@@ -155,15 +155,15 @@ func GetParentNetwork(networkname string) (models.Network, error) {
}
// GetParentNetwork - get parent network
func GetNetworkSettings(networkname string) (models.Network, error) {
func GetNetworkSettings(networkname string) (*models.Network, error) {
var network models.Network
var network *models.Network
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
if err != nil {
return network, err
}
if err = json.Unmarshal([]byte(networkData), &network); err != nil {
return models.Network{}, err
if err = json.Unmarshal([]byte(networkData), network); err != nil {
return &models.Network{}, err
}
network.AccessKeys = []models.AccessKey{}
return network, nil

View File

@@ -213,7 +213,7 @@ func setServerPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) e
device, err := client.Device(iface)
if err != nil {
logger.Log(0, "failed to parse interface")
logger.Log(1, "failed to parse interface")
return err
}
devicePeers := device.Peers

35
main.go
View File

@@ -92,11 +92,6 @@ func startControllers() {
go runGRPC(&waitnetwork)
}
if servercfg.IsClientMode() == "on" {
waitnetwork.Add(1)
go runClient(&waitnetwork)
}
if servercfg.IsDNSMode() {
err := logic.SetDNS()
if err != nil {
@@ -112,27 +107,31 @@ func startControllers() {
}
}
waitnetwork.Add(1)
controller.HandleRESTRequests(&waitnetwork)
go controller.HandleRESTRequests(&waitnetwork)
}
if !servercfg.IsAgentBackend() && !servercfg.IsRestBackend() {
logger.Log(0, "No Server Mode selected, so nothing is being served! Set either Agent mode (AGENT_BACKEND) or Rest mode (REST_BACKEND) to 'true'.")
}
if servercfg.IsClientMode() == "on" {
var checkintime = time.Duration(servercfg.GetServerCheckinInterval()) * time.Second
for { // best effort currently
var netSyncGroup sync.WaitGroup
netSyncGroup.Add(1)
go runClient(&netSyncGroup)
netSyncGroup.Wait()
logger.Log(0, "ran a checkin")
time.Sleep(checkintime)
}
}
waitnetwork.Wait()
logger.Log(0, "exiting")
}
func runClient(wg *sync.WaitGroup) {
defer wg.Done()
go func() {
for {
if err := serverctl.HandleContainedClient(); err != nil {
// PASS
}
var checkintime = time.Duration(servercfg.GetServerCheckinInterval()) * time.Second
time.Sleep(checkintime)
}
}()
go serverctl.HandleContainedClient()
}
func runGRPC(wg *sync.WaitGroup) {
@@ -198,7 +197,3 @@ func setGarbageCollection() {
debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT)
}
}
// func authServerStreamInterceptor() grpc.ServerOption {
// return grpc.StreamInterceptor(controller.AuthServerStreamInterceptor)
// }

View File

@@ -11,7 +11,6 @@ import (
"golang.org/x/crypto/bcrypt"
)
const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const TEN_YEARS_IN_SECONDS = 300000000
const MAX_NAME_LENGTH = 62
@@ -32,7 +31,7 @@ type Node struct {
Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"`
NetworkSettings Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
NetworkSettings *Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
@@ -240,7 +239,7 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.PostDown = currentNode.PostDown
}
if newNode.AllowedIPs == nil {
newNode.AllowedIPs = currentNode.AllowedIPs
newNode.AllowedIPs = currentNode.AllowedIPs[:]
}
if newNode.PersistentKeepalive == 0 {
newNode.PersistentKeepalive = currentNode.PersistentKeepalive
@@ -299,10 +298,10 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.IsIngressGateway = currentNode.IsIngressGateway
}
if newNode.EgressGatewayRanges == nil {
newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges[:]
}
if newNode.IngressGatewayRange == "" {
newNode.IngressGatewayRange = currentNode.IngressGatewayRange
newNode.IngressGatewayRange = currentNode.IngressGatewayRange[:]
}
if newNode.IsStatic == "" {
newNode.IsStatic = currentNode.IsStatic
@@ -344,7 +343,7 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.OS = currentNode.OS
}
if newNode.RelayAddrs == nil {
newNode.RelayAddrs = currentNode.RelayAddrs
newNode.RelayAddrs = currentNode.RelayAddrs[:]
}
if newNode.IsRelay == "" {
newNode.IsRelay = currentNode.IsRelay

View File

@@ -0,0 +1,122 @@
package cli_options
import (
"errors"
"github.com/gravitl/netmaker/netclient/command"
"github.com/gravitl/netmaker/netclient/config"
"github.com/urfave/cli/v2"
)
// GetCommands - return commands that CLI uses
func GetCommands(cliFlags []cli.Flag) []*cli.Command {
return []*cli.Command{
{
Name: "join",
Usage: "Join a Netmaker network.",
Flags: cliFlags,
Action: func(c *cli.Context) error {
cfg, pvtKey, err := config.GetCLIConfig(c)
if err != nil {
return err
}
if cfg.Network == "all" {
err = errors.New("No network provided.")
return err
}
if cfg.Server.GRPCAddress == "" {
err = errors.New("No server address provided.")
return err
}
err = command.Join(cfg, pvtKey)
return err
},
},
{
Name: "leave",
Usage: "Leave a Netmaker network.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Leave(cfg)
return err
},
},
{
Name: "checkin",
Usage: "Checks for local changes and then checks into the specified Netmaker network to ask about remote changes.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.CheckIn(cfg)
return err
},
},
{
Name: "push",
Usage: "Push configuration changes to server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Push(cfg)
return err
},
},
{
Name: "pull",
Usage: "Pull latest configuration and peers from server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Pull(cfg)
return err
},
},
{
Name: "list",
Usage: "Get list of networks.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.List(cfg)
return err
},
},
{
Name: "uninstall",
Usage: "Uninstall the netclient system service.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
err := command.Uninstall()
return err
},
},
}
}

View File

@@ -0,0 +1,196 @@
package cli_options
import "github.com/urfave/cli/v2"
// GetFlags - Returns the flags used by cli
func GetFlags(hostname string) []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
Name: "network",
Aliases: []string{"n"},
EnvVars: []string{"NETCLIENT_NETWORK"},
Value: "all",
Usage: "Network to perform specified action against.",
},
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
EnvVars: []string{"NETCLIENT_PASSWORD"},
Value: "",
Usage: "Password for authenticating with netmaker.",
},
&cli.StringFlag{
Name: "endpoint",
Aliases: []string{"e"},
EnvVars: []string{"NETCLIENT_ENDPOINT"},
Value: "",
Usage: "Reachable (usually public) address for WireGuard (not the private WG address).",
},
&cli.StringFlag{
Name: "macaddress",
Aliases: []string{"m"},
EnvVars: []string{"NETCLIENT_MACADDRESS"},
Value: "",
Usage: "Mac Address for this machine. Used as a unique identifier within Netmaker network.",
},
&cli.StringFlag{
Name: "publickey",
Aliases: []string{"pubkey"},
EnvVars: []string{"NETCLIENT_PUBLICKEY"},
Value: "",
Usage: "Public Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "privatekey",
Aliases: []string{"privkey"},
EnvVars: []string{"NETCLIENT_PRIVATEKEY"},
Value: "",
Usage: "Private Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "port",
EnvVars: []string{"NETCLIENT_PORT"},
Value: "",
Usage: "Port for WireGuard Interface.",
},
&cli.IntFlag{
Name: "keepalive",
EnvVars: []string{"NETCLIENT_KEEPALIVE"},
Value: 0,
Usage: "Default PersistentKeepAlive for Peers in WireGuard Interface.",
},
&cli.StringFlag{
Name: "operatingsystem",
Aliases: []string{"os"},
EnvVars: []string{"NETCLIENT_OS"},
Value: "",
Usage: "Identifiable name for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "name",
EnvVars: []string{"NETCLIENT_NAME"},
Value: hostname,
Usage: "Identifiable name for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "localaddress",
EnvVars: []string{"NETCLIENT_LOCALADDRESS"},
Value: "",
Usage: "Local address for machine. Can be used in place of Endpoint for machines on the same LAN.",
},
&cli.StringFlag{
Name: "isstatic",
Aliases: []string{"st"},
EnvVars: []string{"NETCLIENT_IS_STATIC"},
Value: "",
Usage: "Indicates if client is static by default (will not change addresses automatically).",
},
&cli.StringFlag{
Name: "address",
Aliases: []string{"a"},
EnvVars: []string{"NETCLIENT_ADDRESS"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "addressIPv6",
Aliases: []string{"a6"},
EnvVars: []string{"NETCLIENT_ADDRESSIPV6"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "interface",
Aliases: []string{"i"},
EnvVars: []string{"NETCLIENT_INTERFACE"},
Value: "",
Usage: "WireGuard local network interface name.",
},
&cli.StringFlag{
Name: "apiserver",
EnvVars: []string{"NETCLIENT_API_SERVER"},
Value: "",
Usage: "Address + GRPC Port (e.g. 1.2.3.4:50051) of Netmaker server.",
},
&cli.StringFlag{
Name: "grpcserver",
EnvVars: []string{"NETCLIENT_GRPC_SERVER"},
Value: "",
Usage: "Address + API Port (e.g. 1.2.3.4:8081) of Netmaker server.",
},
&cli.StringFlag{
Name: "key",
Aliases: []string{"k"},
EnvVars: []string{"NETCLIENT_ACCESSKEY"},
Value: "",
Usage: "Access Key for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
EnvVars: []string{"NETCLIENT_ACCESSTOKEN"},
Value: "",
Usage: "Access Token for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "localrange",
EnvVars: []string{"NETCLIENT_LOCALRANGE"},
Value: "",
Usage: "Local Range if network is local, for instance 192.168.1.0/24.",
},
&cli.StringFlag{
Name: "dnson",
EnvVars: []string{"NETCLIENT_DNS"},
Value: "yes",
Usage: "Sets private dns if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "islocal",
EnvVars: []string{"NETCLIENT_IS_LOCAL"},
Value: "",
Usage: "Sets endpoint to local address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "isdualstack",
EnvVars: []string{"NETCLIENT_IS_DUALSTACK"},
Value: "",
Usage: "Sets ipv6 address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "udpholepunch",
EnvVars: []string{"NETCLIENT_UDP_HOLEPUNCH"},
Value: "",
Usage: "Turns on udp holepunching if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "ipforwarding",
EnvVars: []string{"NETCLIENT_IPFORWARDING"},
Value: "on",
Usage: "Sets ip forwarding on if 'on'. Ignores if 'off'. On by default.",
},
&cli.StringFlag{
Name: "postup",
EnvVars: []string{"NETCLIENT_POSTUP"},
Value: "",
Usage: "Sets PostUp command for WireGuard.",
},
&cli.StringFlag{
Name: "postdown",
EnvVars: []string{"NETCLIENT_POSTDOWN"},
Value: "",
Usage: "Sets PostDown command for WireGuard.",
},
&cli.StringFlag{
Name: "daemon",
EnvVars: []string{"NETCLIENT_DAEMON"},
Value: "on",
Usage: "Installs daemon if 'on'. Ignores if 'off'. On by default.",
},
&cli.StringFlag{
Name: "roaming",
EnvVars: []string{"NETCLIENT_ROAMING"},
Value: "yes",
Usage: "Checks for IP changes if 'yes'. Ignores if 'no'. Yes by default.",
},
}
}

View File

@@ -72,90 +72,6 @@ func Write(config *ClientConfig, network string) error {
return err
}
// WriteServer - writes the config of a server to disk for client
func WriteServer(server string, accesskey string, network string) error {
if network == "" {
err := errors.New("no network provided - exiting")
return err
}
nofile := false
//home, err := homedir.Dir()
_, err := os.Stat(ncutils.GetNetclientPath() + "/config")
if os.IsNotExist(err) {
os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744)
} else if err != nil {
fmt.Println("couldnt find or create", ncutils.GetNetclientPath())
return err
}
home := ncutils.GetNetclientPathSpecific()
file := fmt.Sprintf(home + "netconfig-" + network)
//f, err := os.Open(file)
f, err := os.OpenFile(file, os.O_CREATE|os.O_RDWR, 0666)
//f, err := ioutil.ReadFile(file)
if err != nil {
fmt.Println("couldnt open netconfig-" + network)
fmt.Println(err)
nofile = true
//err = nil
return err
}
defer f.Close()
//cfg := &ClientConfig{}
var cfg ClientConfig
if !nofile {
fmt.Println("Writing to existing config file at " + home + "netconfig-" + network)
decoder := yaml.NewDecoder(f)
err = decoder.Decode(&cfg)
//err = yaml.Unmarshal(f, &cfg)
if err != nil {
//fmt.Println(err)
//return err
}
f.Close()
f, err = os.OpenFile(file, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
if err != nil {
fmt.Println("couldnt open netconfig")
fmt.Println(err)
nofile = true
//err = nil
return err
}
defer f.Close()
if err != nil {
fmt.Println("trouble opening file")
fmt.Println(err)
}
cfg.Server.GRPCAddress = server
cfg.Server.AccessKey = accesskey
err = yaml.NewEncoder(f).Encode(cfg)
//_, err = yaml.Marshal(f, &cfg)
if err != nil {
fmt.Println("trouble encoding file")
return err
}
} else {
fmt.Println("Creating new config file at " + home + "netconfig-" + network)
cfg.Server.GRPCAddress = server
cfg.Server.AccessKey = accesskey
newf, err := os.Create(home + "netconfig-" + network)
err = yaml.NewEncoder(newf).Encode(cfg)
defer newf.Close()
if err != nil {
return err
}
}
return err
}
// ClientConfig.ReadConfig - used to read config from client disk into memory
func (config *ClientConfig) ReadConfig() {
@@ -192,7 +108,6 @@ func (config *ClientConfig) ReadConfig() {
// ModConfig - overwrites the node inside client config on disk
func ModConfig(node *models.Node) error {
network := node.Network
networksettings := node.NetworkSettings
if network == "" {
return errors.New("no network provided")
}
@@ -207,7 +122,7 @@ func ModConfig(node *models.Node) error {
}
modconfig.Node = (*node)
modconfig.NetworkSettings = (networksettings)
modconfig.NetworkSettings = (*node.NetworkSettings)
err = Write(&modconfig, network)
return err
}

View File

@@ -3,18 +3,12 @@
package main
import (
"errors"
"log"
"os"
"os/exec"
"os/signal"
"runtime/debug"
"strconv"
"syscall"
"github.com/gravitl/netmaker/netclient/cli_options"
"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/urfave/cli/v2"
@@ -24,360 +18,20 @@ 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.9.1"
app.Version = "v0.9.2"
hostname, err := os.Hostname()
if err != nil {
hostname = ""
}
cliFlags := []cli.Flag{
&cli.StringFlag{
Name: "network",
Aliases: []string{"n"},
EnvVars: []string{"NETCLIENT_NETWORK"},
Value: "all",
Usage: "Network to perform specified action against.",
},
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
EnvVars: []string{"NETCLIENT_PASSWORD"},
Value: "",
Usage: "Password for authenticating with netmaker.",
},
&cli.StringFlag{
Name: "endpoint",
Aliases: []string{"e"},
EnvVars: []string{"NETCLIENT_ENDPOINT"},
Value: "",
Usage: "Reachable (usually public) address for WireGuard (not the private WG address).",
},
&cli.StringFlag{
Name: "macaddress",
Aliases: []string{"m"},
EnvVars: []string{"NETCLIENT_MACADDRESS"},
Value: "",
Usage: "Mac Address for this machine. Used as a unique identifier within Netmaker network.",
},
&cli.StringFlag{
Name: "publickey",
Aliases: []string{"pubkey"},
EnvVars: []string{"NETCLIENT_PUBLICKEY"},
Value: "",
Usage: "Public Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "privatekey",
Aliases: []string{"privkey"},
EnvVars: []string{"NETCLIENT_PRIVATEKEY"},
Value: "",
Usage: "Private Key for WireGuard Interface.",
},
&cli.StringFlag{
Name: "port",
EnvVars: []string{"NETCLIENT_PORT"},
Value: "",
Usage: "Port for WireGuard Interface.",
},
&cli.IntFlag{
Name: "keepalive",
EnvVars: []string{"NETCLIENT_KEEPALIVE"},
Value: 0,
Usage: "Default PersistentKeepAlive for Peers in WireGuard Interface.",
},
&cli.StringFlag{
Name: "operatingsystem",
Aliases: []string{"os"},
EnvVars: []string{"NETCLIENT_OS"},
Value: "",
Usage: "Identifiable name for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "name",
EnvVars: []string{"NETCLIENT_NAME"},
Value: hostname,
Usage: "Identifiable name for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "localaddress",
EnvVars: []string{"NETCLIENT_LOCALADDRESS"},
Value: "",
Usage: "Local address for machine. Can be used in place of Endpoint for machines on the same LAN.",
},
&cli.StringFlag{
Name: "isstatic",
Aliases: []string{"st"},
EnvVars: []string{"NETCLIENT_IS_STATIC"},
Value: "",
Usage: "Indicates if client is static by default (will not change addresses automatically).",
},
&cli.StringFlag{
Name: "address",
Aliases: []string{"a"},
EnvVars: []string{"NETCLIENT_ADDRESS"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "addressIPv6",
Aliases: []string{"a6"},
EnvVars: []string{"NETCLIENT_ADDRESSIPV6"},
Value: "",
Usage: "WireGuard address for machine within Netmaker network.",
},
&cli.StringFlag{
Name: "interface",
Aliases: []string{"i"},
EnvVars: []string{"NETCLIENT_INTERFACE"},
Value: "",
Usage: "WireGuard local network interface name.",
},
&cli.StringFlag{
Name: "apiserver",
EnvVars: []string{"NETCLIENT_API_SERVER"},
Value: "",
Usage: "Address + GRPC Port (e.g. 1.2.3.4:50051) of Netmaker server.",
},
&cli.StringFlag{
Name: "grpcserver",
EnvVars: []string{"NETCLIENT_GRPC_SERVER"},
Value: "",
Usage: "Address + API Port (e.g. 1.2.3.4:8081) of Netmaker server.",
},
&cli.StringFlag{
Name: "key",
Aliases: []string{"k"},
EnvVars: []string{"NETCLIENT_ACCESSKEY"},
Value: "",
Usage: "Access Key for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
EnvVars: []string{"NETCLIENT_ACCESSTOKEN"},
Value: "",
Usage: "Access Token for signing up machine with Netmaker server during initial 'add'.",
},
&cli.StringFlag{
Name: "localrange",
EnvVars: []string{"NETCLIENT_LOCALRANGE"},
Value: "",
Usage: "Local Range if network is local, for instance 192.168.1.0/24.",
},
&cli.StringFlag{
Name: "dnson",
EnvVars: []string{"NETCLIENT_DNS"},
Value: "yes",
Usage: "Sets private dns if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "islocal",
EnvVars: []string{"NETCLIENT_IS_LOCAL"},
Value: "",
Usage: "Sets endpoint to local address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "isdualstack",
EnvVars: []string{"NETCLIENT_IS_DUALSTACK"},
Value: "",
Usage: "Sets ipv6 address if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "udpholepunch",
EnvVars: []string{"NETCLIENT_UDP_HOLEPUNCH"},
Value: "",
Usage: "Turns on udp holepunching if 'yes'. Ignores if 'no'. Will retrieve from network if unset.",
},
&cli.StringFlag{
Name: "ipforwarding",
EnvVars: []string{"NETCLIENT_IPFORWARDING"},
Value: "on",
Usage: "Sets ip forwarding on if 'on'. Ignores if 'off'. On by default.",
},
&cli.StringFlag{
Name: "postup",
EnvVars: []string{"NETCLIENT_POSTUP"},
Value: "",
Usage: "Sets PostUp command for WireGuard.",
},
&cli.StringFlag{
Name: "postdown",
EnvVars: []string{"NETCLIENT_POSTDOWN"},
Value: "",
Usage: "Sets PostDown command for WireGuard.",
},
&cli.StringFlag{
Name: "daemon",
EnvVars: []string{"NETCLIENT_DAEMON"},
Value: "on",
Usage: "Installs daemon if 'on'. Ignores if 'off'. On by default.",
},
&cli.StringFlag{
Name: "roaming",
EnvVars: []string{"NETCLIENT_ROAMING"},
Value: "yes",
Usage: "Checks for IP changes if 'yes'. Ignores if 'no'. Yes by default.",
},
}
app.Commands = []*cli.Command{
{
Name: "join",
Usage: "Join a Netmaker network.",
Flags: cliFlags,
Action: func(c *cli.Context) error {
cfg, pvtKey, err := config.GetCLIConfig(c)
if err != nil {
return err
}
if cfg.Network == "all" {
err = errors.New("No network provided.")
return err
}
if cfg.Server.GRPCAddress == "" {
err = errors.New("No server address provided.")
return err
}
err = command.Join(cfg, pvtKey)
return err
},
},
{
Name: "leave",
Usage: "Leave a Netmaker network.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Leave(cfg)
return err
},
},
{
Name: "checkin",
Usage: "Checks for local changes and then checks into the specified Netmaker network to ask about remote changes.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.CheckIn(cfg)
return err
},
},
{
Name: "push",
Usage: "Push configuration changes to server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Push(cfg)
return err
},
},
{
Name: "pull",
Usage: "Pull latest configuration and peers from server.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.Pull(cfg)
return err
},
},
{
Name: "list",
Usage: "Get list of networks.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
cfg, _, err := config.GetCLIConfig(c)
if err != nil {
return err
}
err = command.List(cfg)
return err
},
},
{
Name: "uninstall",
Usage: "Uninstall the netclient system service.",
Flags: cliFlags,
// the action, or code that will be executed when
// we execute our `ns` command
Action: func(c *cli.Context) error {
err := command.Uninstall()
return err
},
},
}
cliFlags := cli_options.GetFlags(ncutils.GetHostname())
app.Commands = cli_options.GetCommands(cliFlags[:])
setGarbageCollection()
if ncutils.IsWindows() {
ncwindows.InitWindows()
} else {
// start our application
out, err := ncutils.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.")
}
_, err = exec.LookPath("wg")
uspace := ncutils.GetWireGuard()
if err != nil {
if uspace == "wg" {
log.Println(err)
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
}
ncutils.PrintLog("Running with userspace wireguard: "+uspace, 0)
} else if uspace != "wg" {
log.Println("running userspace WireGuard with " + uspace)
}
}
if !ncutils.IsKernel() {
if !local.IsWGInstalled() {
log.Fatal("Please install WireGuard before using Gravitl Netclient. https://download.wireguard.com")
}
ncutils.CheckUID()
ncutils.CheckWG()
}
if len(os.Args) == 1 && ncutils.IsWindows() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Println("closing Gravitl Netclient")
os.Exit(0)
}()
command.RunUserspaceDaemon()
} else {
err := app.Run(os.Args)

View File

@@ -24,6 +24,9 @@ import (
"google.golang.org/grpc/credentials"
)
// 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"
@@ -447,3 +450,47 @@ func DNSFormatString(input string) string {
}
return reg.ReplaceAllString(input, "")
}
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
}
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.")
}
}
// CheckWG - Checks if WireGuard is installed. If not, exit
func CheckWG() {
var _, err = exec.LookPath("wg")
uspace := GetWireGuard()
if err != nil {
if uspace == "wg" {
PrintLog(err.Error(), 0)
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
}
PrintLog("Running with userspace wireguard: "+uspace, 0)
} else if uspace != "wg" {
log.Println("running userspace WireGuard with " + uspace)
}
}