mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-17 22:31:23 +08:00
memory issue work
This commit is contained in:
@@ -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
|
||||
|
@@ -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
33
controllers/debug.go
Normal 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())
|
||||
}()
|
||||
}
|
@@ -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
|
||||
|
@@ -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
35
main.go
@@ -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)
|
||||
// }
|
||||
|
@@ -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
|
||||
|
122
netclient/cli_options/cmds.go
Normal file
122
netclient/cli_options/cmds.go
Normal 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
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
196
netclient/cli_options/flags.go
Normal file
196
netclient/cli_options/flags.go
Normal 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.",
|
||||
},
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user