| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528 | package configimport (	//"github.com/davecgh/go-spew/spew"	"github.com/urfave/cli/v2"	"os"        "encoding/base64"	"errors"	"strings"	"fmt"	"log"	"gopkg.in/yaml.v3"	nodepb "github.com/gravitl/netmaker/grpc"	"github.com/gravitl/netmaker/models")type GlobalConfig struct {	Client models.IntClient}type ClientConfig struct {	Server ServerConfig `yaml:"server"`	Node NodeConfig `yaml:"node"`	Network string `yaml:"network"`	Daemon string `yaml:"daemon"`	OperatingSystem string `yaml:"operatingsystem"`}type ServerConfig struct {        GRPCAddress string `yaml:"grpcaddress"`        APIAddress string `yaml:"apiaddress"`        AccessKey string `yaml:"accesskey"`}type ListConfig struct {        Name string `yaml:"name"`        Interface string `yaml:"interface"`        PrivateIPv4 string `yaml:"wgaddress"`        PrivateIPv6 string `yaml:"wgaddress6"`        PublicEndpoint string `yaml:"endpoint"`}type NodeConfig struct {        Name string `yaml:"name"`        Interface string `yaml:"interface"`        Network string `yaml:"network"`        Password string `yaml:"password"`        MacAddress string `yaml:"macaddress"`        LocalAddress string `yaml:"localaddress"`        WGAddress string `yaml:"wgaddress"`        WGAddress6 string `yaml:"wgaddress6"`        Roaming string `yaml:"roaming"`        DNS string `yaml:"dns"`        IsLocal string `yaml:"islocal"`        IsDualStack string `yaml:"isdualstack"`        IsIngressGateway string `yaml:"isingressgateway"`        AllowedIPs string `yaml:"allowedips"`        LocalRange string `yaml:"localrange"`        PostUp string `yaml:"postup"`        PostDown string `yaml:"postdown"`        Port int32 `yaml:"port"`        KeepAlive int32 `yaml:"keepalive"`        PublicKey string `yaml:"publickey"`        PrivateKey string `yaml:"privatekey"`        Endpoint string `yaml:"endpoint"`        PostChanges string `yaml:"postchanges"`        IPForwarding string `yaml:"ipforwarding"`}//reading in the env filefunc Write(config *ClientConfig, network string) error{	if network == "" {		err := errors.New("No network provided. Exiting.")		return err	}        _, err := os.Stat("/etc/netclient") 	if os.IsNotExist(err) {		      os.Mkdir("/etc/netclient", 744)	} else if err != nil {                return err        }	home := "/etc/netclient"        if err != nil {                log.Fatal(err)        }        file := fmt.Sprintf(home + "/netconfig-" + network)        f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)        defer f.Close()	err = yaml.NewEncoder(f).Encode(config)	if err != nil {		return err	}        return err}//reading in the env filefunc WriteGlobal(config *GlobalConfig) error{        _, err := os.Stat("/etc/netclient")         if os.IsNotExist(err) {                      os.Mkdir("/etc/netclient", 744)        } else if err != nil {                return err        }        home := "/etc/netclient"        if err != nil {                log.Fatal(err)        }        file := fmt.Sprintf(home + "/netconfig-global-001")        f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)        defer f.Close()        err = yaml.NewEncoder(f).Encode(config)        if err != nil {                return err        }        return err}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("/etc/netclient")	if os.IsNotExist(err) {                os.Mkdir("/etc/netclient", 744)        } else if err != nil {		fmt.Println("couldnt find or create /etc/netclient")                return err        }        home := "/etc/netclient"	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}func(config *ClientConfig) ReadConfig() {	nofile := false	//home, err := homedir.Dir()	home := "/etc/netclient"	file := fmt.Sprintf(home + "/netconfig-" + config.Network)	//f, err := os.Open(file)        f, err := os.OpenFile(file, os.O_RDONLY, 0666)	if err != nil {		fmt.Println("trouble opening file")		fmt.Println(err)		nofile = true		//fmt.Println("Could not access " + home + "/.netconfig,  proceeding...")	}	defer f.Close()	//var cfg ClientConfig	if !nofile {		decoder := yaml.NewDecoder(f)		err = decoder.Decode(&config)		if err != nil {			fmt.Println("no config or invalid")			fmt.Println(err)			log.Fatal(err)		} else {			//config = cfg		}	}}func ModGlobalConfig(cfg models.IntClient) error{        var modconfig GlobalConfig        var err error        if FileExists("/etc/netclient/netconfig-global-001") {                useconfig, err := ReadGlobalConfig()                if err != nil {                        return err                }                modconfig = *useconfig        }        if cfg.ServerPort != ""{                modconfig.Client.ServerPort = cfg.ServerPort        }        if cfg.PublicKey != ""{                modconfig.Client.PublicKey = cfg.PublicKey        }        if cfg.PrivateKey != ""{                modconfig.Client.PrivateKey = cfg.PrivateKey        }        if cfg.ServerWGEndpoint != ""{                modconfig.Client.ServerWGEndpoint = cfg.ServerWGEndpoint        }        if cfg.ServerAddress != ""{                modconfig.Client.ServerAddress = cfg.ServerAddress        }	if cfg.Address != ""{                modconfig.Client.Address = cfg.Address        }        if cfg.Address6 != ""{                modconfig.Client.Address6 = cfg.Address6        }        if cfg.Network != ""{                modconfig.Client.Network = cfg.Network        }        if cfg.ServerKey != ""{                modconfig.Client.ServerKey = cfg.ServerKey        }        err = WriteGlobal(&modconfig)        return err}func ModConfig(node *nodepb.Node) error{        network := node.Nodenetwork        if network == "" {                return errors.New("No Network Provided")        }	var modconfig ClientConfig	var err error	if FileExists("/etc/netclient/netconfig-"+network) {		useconfig, err := ReadConfig(network)		if err != nil {			return err		}		modconfig = *useconfig	}        nodecfg := modconfig.Node        if node.Name != ""{                nodecfg.Name = node.Name        }        if node.Interface != ""{                nodecfg.Interface = node.Interface        }        if node.Nodenetwork != ""{                nodecfg.Network = node.Nodenetwork        }        if node.Macaddress != ""{                nodecfg.MacAddress = node.Macaddress        }        if node.Localaddress != ""{                nodecfg.LocalAddress = node.Localaddress        }        if node.Postup != ""{                nodecfg.PostUp = node.Postup        }        if node.Postdown != ""{                nodecfg.PostDown = node.Postdown        }        if node.Listenport != 0{                nodecfg.Port = node.Listenport        }        if node.Keepalive != 0{                nodecfg.KeepAlive = node.Keepalive        }        if node.Publickey != ""{                nodecfg.PublicKey = node.Publickey        }        if node.Endpoint != ""{                nodecfg.Endpoint = node.Endpoint        }        if node.Password != ""{                nodecfg.Password = node.Password        }        if node.Address != ""{                nodecfg.WGAddress = node.Address        }        if node.Address6 != ""{                nodecfg.WGAddress6 = node.Address6        }        if node.Postchanges != "" {                nodecfg.PostChanges = node.Postchanges        }        if node.Dnsoff == true {		nodecfg.DNS = "off"        }        if node.Isdualstack == true {                nodecfg.IsDualStack = "yes"        }	if node.Isingressgateway {		nodecfg.IsIngressGateway = "yes"	} else {                nodecfg.IsIngressGateway = "no"	}        if node.Localrange != "" && node.Islocal {                nodecfg.IsLocal = "yes"                nodecfg.LocalRange = node.Localrange        }        modconfig.Node = nodecfg        err = Write(&modconfig, network)        return err}func GetCLIConfig(c *cli.Context) (ClientConfig, error){	var cfg ClientConfig	if c.String("token") != "" {                tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))                if err  != nil {			log.Println("error decoding token")			return cfg, err                }                token := string(tokenbytes)                tokenvals := strings.Split(token, "|")                cfg.Server.GRPCAddress = tokenvals[0]                cfg.Server.APIAddress = tokenvals[1]                cfg.Network = tokenvals[2]                cfg.Node.Network = tokenvals[2]                cfg.Server.AccessKey = tokenvals[3]                cfg.Node.LocalRange = tokenvals[4]		if c.String("grpcserver") != "" {			cfg.Server.GRPCAddress = c.String("grpcserver")		}                if c.String("apiserver") != "" {                        cfg.Server.APIAddress = c.String("apiserver")                }		if c.String("key") != "" {			cfg.Server.AccessKey = c.String("key")		}		if c.String("network") != "all" {			cfg.Network = c.String("network")			cfg.Node.Network = c.String("network")		}		if c.String("localrange") != "" {			cfg.Node.LocalRange = c.String("localrange")		}	} else {		cfg.Server.GRPCAddress = c.String("grpcserver")		cfg.Server.APIAddress = c.String("apiserver")		cfg.Server.AccessKey = c.String("key")                cfg.Network = c.String("network")                cfg.Node.Network = c.String("network")                cfg.Node.LocalRange = c.String("localrange")	}	cfg.Node.Name = c.String("name")	cfg.Node.Interface = c.String("interface")	cfg.Node.Password = c.String("password")	cfg.Node.MacAddress = c.String("macaddress")	cfg.Node.LocalAddress = c.String("localaddress")	cfg.Node.LocalRange = c.String("localrange")	cfg.Node.WGAddress = c.String("address")	cfg.Node.WGAddress6 = c.String("addressIPV6")	cfg.Node.Roaming = c.String("")	cfg.Node.DNS = c.String("")	cfg.Node.IsLocal = c.String("")	cfg.Node.IsDualStack = c.String("")	cfg.Node.IsIngressGateway = c.String("")	cfg.Node.PostUp = c.String("")	cfg.Node.PostDown = c.String("")	cfg.Node.Port = int32(c.Int(""))	cfg.Node.KeepAlive = int32(c.Int(""))	cfg.Node.PublicKey = c.String("")	cfg.Node.PrivateKey = c.String("")	cfg.Node.Endpoint = c.String("")	cfg.Node.IPForwarding = c.String("")	return cfg, nil}func GetCLIConfigRegister(c *cli.Context) (GlobalConfig, error){	var cfg GlobalConfig        if c.String("token") != "" {                tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))                if err  != nil {                        log.Println("error decoding token")                        return cfg, err                }                token := string(tokenbytes)                tokenvals := strings.Split(token, "|")                cfg.Client.ServerAddress = tokenvals[0]                cfg.Client.ServerAPIEndpoint = tokenvals[1]		servervals := strings.Split(tokenvals[1], ":")		wgvals := strings.Split(tokenvals[0], ":")		cfg.Client.ServerWGEndpoint = servervals[0]                cfg.Client.ServerAddress = wgvals[0]                cfg.Client.ServerPort = wgvals[1]		cfg.Client.ServerKey = tokenvals[3]                if c.String("grpcserver") != "" {                        cfg.Client.ServerAddress = c.String("grpcserver")                }                if c.String("apiserver") != "" {                        cfg.Client.ServerAPIEndpoint = c.String("apiserver")                }                if c.String("key") != "" {                        cfg.Client.ServerKey = c.String("key")                }                if c.String("network") != "all" {                        cfg.Client.Network = c.String("network")                }        } else {                cfg.Client.ServerAddress = c.String("grpcserver")                cfg.Client.ServerWGEndpoint = c.String("apiserver")                cfg.Client.ServerKey = c.String("key")                cfg.Client.Network = c.String("network")        }        cfg.Client.Address = c.String("address")        cfg.Client.Address6 = c.String("addressIPV6")        cfg.Client.PublicKey = c.String("pubkey")        cfg.Client.PrivateKey = c.String("privkey")        return cfg, nil}func ReadConfig(network string) (*ClientConfig, error) {        if network == "" {                err := errors.New("No network provided. Exiting.")                return nil, err        }	nofile := false	home := "/etc/netclient"	file := fmt.Sprintf(home + "/netconfig-" + network)	f, err := os.Open(file)	if err != nil {		nofile = true	}	defer f.Close()	var cfg ClientConfig	if !nofile {		decoder := yaml.NewDecoder(f)		err = decoder.Decode(&cfg)		if err != nil {			fmt.Println("trouble decoding file")			return nil, err		}	}	return &cfg, err}func ReadGlobalConfig() (*GlobalConfig, error) {        nofile := false        home := "/etc/netclient"        file := fmt.Sprintf(home + "/netconfig-global-001")        f, err := os.Open(file)        if err != nil {                nofile = true        }        defer f.Close()        var cfg GlobalConfig        if !nofile {                decoder := yaml.NewDecoder(f)                err = decoder.Decode(&cfg)                if err != nil {                        fmt.Println("trouble decoding file")                        return nil, err                }        }        return &cfg, err}func FileExists(f string) bool {    info, err := os.Stat(f)    if os.IsNotExist(err) {        return false    }    return !info.IsDir()}
 |