config.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. package config
  2. import (
  3. //"github.com/davecgh/go-spew/spew"
  4. "github.com/urfave/cli/v2"
  5. "os"
  6. "encoding/base64"
  7. "errors"
  8. "strings"
  9. "fmt"
  10. "net"
  11. "log"
  12. "gopkg.in/yaml.v3"
  13. nodepb "github.com/gravitl/netmaker/grpc"
  14. "github.com/gravitl/netmaker/models"
  15. )
  16. type GlobalConfig struct {
  17. Client models.IntClient
  18. }
  19. type ClientConfig struct {
  20. Server ServerConfig `yaml:"server"`
  21. Node NodeConfig `yaml:"node"`
  22. Network string `yaml:"network"`
  23. Daemon string `yaml:"daemon"`
  24. OperatingSystem string `yaml:"operatingsystem"`
  25. }
  26. type ServerConfig struct {
  27. GRPCAddress string `yaml:"grpcaddress"`
  28. APIAddress string `yaml:"apiaddress"`
  29. AccessKey string `yaml:"accesskey"`
  30. }
  31. type ListConfig struct {
  32. Name string `yaml:"name"`
  33. Interface string `yaml:"interface"`
  34. PrivateIPv4 string `yaml:"wgaddress"`
  35. PrivateIPv6 string `yaml:"wgaddress6"`
  36. PublicEndpoint string `yaml:"endpoint"`
  37. }
  38. type NodeConfig struct {
  39. Name string `yaml:"name"`
  40. Interface string `yaml:"interface"`
  41. Network string `yaml:"network"`
  42. Password string `yaml:"password"`
  43. MacAddress string `yaml:"macaddress"`
  44. LocalAddress string `yaml:"localaddress"`
  45. WGAddress string `yaml:"wgaddress"`
  46. WGAddress6 string `yaml:"wgaddress6"`
  47. Roaming string `yaml:"roaming"`
  48. DNS string `yaml:"dns"`
  49. IsLocal string `yaml:"islocal"`
  50. IsDualStack string `yaml:"isdualstack"`
  51. IsIngressGateway string `yaml:"isingressgateway"`
  52. AllowedIPs string `yaml:"allowedips"`
  53. LocalRange string `yaml:"localrange"`
  54. PostUp string `yaml:"postup"`
  55. PostDown string `yaml:"postdown"`
  56. Port int32 `yaml:"port"`
  57. KeepAlive int32 `yaml:"keepalive"`
  58. PublicKey string `yaml:"publickey"`
  59. PrivateKey string `yaml:"privatekey"`
  60. Endpoint string `yaml:"endpoint"`
  61. PostChanges string `yaml:"postchanges"`
  62. IPForwarding string `yaml:"ipforwarding"`
  63. }
  64. //reading in the env file
  65. func Write(config *ClientConfig, network string) error{
  66. if network == "" {
  67. err := errors.New("No network provided. Exiting.")
  68. return err
  69. }
  70. _, err := os.Stat("/etc/netclient")
  71. if os.IsNotExist(err) {
  72. os.Mkdir("/etc/netclient", 744)
  73. } else if err != nil {
  74. return err
  75. }
  76. home := "/etc/netclient"
  77. if err != nil {
  78. log.Fatal(err)
  79. }
  80. file := fmt.Sprintf(home + "/netconfig-" + network)
  81. f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
  82. defer f.Close()
  83. err = yaml.NewEncoder(f).Encode(config)
  84. if err != nil {
  85. return err
  86. }
  87. return err
  88. }
  89. //reading in the env file
  90. func WriteGlobal(config *GlobalConfig) error{
  91. _, err := os.Stat("/etc/netclient")
  92. if os.IsNotExist(err) {
  93. os.Mkdir("/etc/netclient", 744)
  94. } else if err != nil {
  95. return err
  96. }
  97. home := "/etc/netclient"
  98. if err != nil {
  99. log.Fatal(err)
  100. }
  101. file := fmt.Sprintf(home + "/netconfig-global-001")
  102. f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
  103. defer f.Close()
  104. err = yaml.NewEncoder(f).Encode(config)
  105. if err != nil {
  106. return err
  107. }
  108. return err
  109. }
  110. func WriteServer(server string, accesskey string, network string) error{
  111. if network == "" {
  112. err := errors.New("No network provided. Exiting.")
  113. return err
  114. }
  115. nofile := false
  116. //home, err := homedir.Dir()
  117. _, err := os.Stat("/etc/netclient")
  118. if os.IsNotExist(err) {
  119. os.Mkdir("/etc/netclient", 744)
  120. } else if err != nil {
  121. fmt.Println("couldnt find or create /etc/netclient")
  122. return err
  123. }
  124. home := "/etc/netclient"
  125. file := fmt.Sprintf(home + "/netconfig-" + network)
  126. //f, err := os.Open(file)
  127. f, err := os.OpenFile(file, os.O_CREATE|os.O_RDWR, 0666)
  128. //f, err := ioutil.ReadFile(file)
  129. if err != nil {
  130. fmt.Println("couldnt open netconfig-" + network)
  131. fmt.Println(err)
  132. nofile = true
  133. //err = nil
  134. return err
  135. }
  136. defer f.Close()
  137. //cfg := &ClientConfig{}
  138. var cfg ClientConfig
  139. if !nofile {
  140. fmt.Println("Writing to existing config file at " + home + "/netconfig-" + network)
  141. decoder := yaml.NewDecoder(f)
  142. err = decoder.Decode(&cfg)
  143. //err = yaml.Unmarshal(f, &cfg)
  144. if err != nil {
  145. //fmt.Println(err)
  146. //return err
  147. }
  148. f.Close()
  149. f, err = os.OpenFile(file, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
  150. if err != nil {
  151. fmt.Println("couldnt open netconfig")
  152. fmt.Println(err)
  153. nofile = true
  154. //err = nil
  155. return err
  156. }
  157. defer f.Close()
  158. if err != nil {
  159. fmt.Println("trouble opening file")
  160. fmt.Println(err)
  161. }
  162. cfg.Server.GRPCAddress = server
  163. cfg.Server.AccessKey = accesskey
  164. err = yaml.NewEncoder(f).Encode(cfg)
  165. //_, err = yaml.Marshal(f, &cfg)
  166. if err != nil {
  167. fmt.Println("trouble encoding file")
  168. return err
  169. }
  170. } else {
  171. fmt.Println("Creating new config file at " + home + "/netconfig-" + network)
  172. cfg.Server.GRPCAddress = server
  173. cfg.Server.AccessKey = accesskey
  174. newf, err := os.Create(home + "/netconfig-" + network)
  175. err = yaml.NewEncoder(newf).Encode(cfg)
  176. defer newf.Close()
  177. if err != nil {
  178. return err
  179. }
  180. }
  181. return err
  182. }
  183. func(config *ClientConfig) ReadConfig() {
  184. nofile := false
  185. //home, err := homedir.Dir()
  186. home := "/etc/netclient"
  187. file := fmt.Sprintf(home + "/netconfig-" + config.Network)
  188. //f, err := os.Open(file)
  189. f, err := os.OpenFile(file, os.O_RDONLY, 0666)
  190. if err != nil {
  191. fmt.Println("trouble opening file")
  192. fmt.Println(err)
  193. nofile = true
  194. //fmt.Println("Could not access " + home + "/.netconfig, proceeding...")
  195. }
  196. defer f.Close()
  197. //var cfg ClientConfig
  198. if !nofile {
  199. decoder := yaml.NewDecoder(f)
  200. err = decoder.Decode(&config)
  201. if err != nil {
  202. fmt.Println("no config or invalid")
  203. fmt.Println(err)
  204. log.Fatal(err)
  205. } else {
  206. //config = cfg
  207. }
  208. }
  209. }
  210. func ModGlobalConfig(cfg models.IntClient) error{
  211. var modconfig GlobalConfig
  212. var err error
  213. if FileExists("/etc/netclient/netconfig-global-001") {
  214. useconfig, err := ReadGlobalConfig()
  215. if err != nil {
  216. return err
  217. }
  218. modconfig = *useconfig
  219. }
  220. if cfg.ServerWGPort != ""{
  221. modconfig.Client.ServerWGPort = cfg.ServerWGPort
  222. }
  223. if cfg.ServerGRPCPort != ""{
  224. modconfig.Client.ServerGRPCPort = cfg.ServerGRPCPort
  225. }
  226. if cfg.ServerAPIPort != ""{
  227. modconfig.Client.ServerAPIPort = cfg.ServerAPIPort
  228. }
  229. if cfg.PublicKey != ""{
  230. modconfig.Client.PublicKey = cfg.PublicKey
  231. }
  232. if cfg.PrivateKey != ""{
  233. modconfig.Client.PrivateKey = cfg.PrivateKey
  234. }
  235. if cfg.ServerPublicEndpoint != ""{
  236. modconfig.Client.ServerPublicEndpoint = cfg.ServerPublicEndpoint
  237. }
  238. if cfg.ServerPrivateAddress != ""{
  239. modconfig.Client.ServerPrivateAddress = cfg.ServerPrivateAddress
  240. }
  241. if cfg.Address != ""{
  242. modconfig.Client.Address = cfg.Address
  243. }
  244. if cfg.Address6 != ""{
  245. modconfig.Client.Address6 = cfg.Address6
  246. }
  247. if cfg.Network != ""{
  248. modconfig.Client.Network = cfg.Network
  249. }
  250. if cfg.ServerKey != ""{
  251. modconfig.Client.ServerKey = cfg.ServerKey
  252. }
  253. if cfg.AccessKey != ""{
  254. modconfig.Client.AccessKey = cfg.AccessKey
  255. }
  256. if cfg.ClientID != ""{
  257. modconfig.Client.ClientID = cfg.ClientID
  258. }
  259. err = WriteGlobal(&modconfig)
  260. return err
  261. }
  262. func ModConfig(node *nodepb.Node) error{
  263. network := node.Nodenetwork
  264. if network == "" {
  265. return errors.New("No Network Provided")
  266. }
  267. var modconfig ClientConfig
  268. var err error
  269. if FileExists("/etc/netclient/netconfig-"+network) {
  270. useconfig, err := ReadConfig(network)
  271. if err != nil {
  272. return err
  273. }
  274. modconfig = *useconfig
  275. }
  276. nodecfg := modconfig.Node
  277. if node.Name != ""{
  278. nodecfg.Name = node.Name
  279. }
  280. if node.Interface != ""{
  281. nodecfg.Interface = node.Interface
  282. }
  283. if node.Nodenetwork != ""{
  284. nodecfg.Network = node.Nodenetwork
  285. }
  286. if node.Macaddress != ""{
  287. nodecfg.MacAddress = node.Macaddress
  288. }
  289. if node.Localaddress != ""{
  290. nodecfg.LocalAddress = node.Localaddress
  291. }
  292. if node.Postup != ""{
  293. nodecfg.PostUp = node.Postup
  294. }
  295. if node.Postdown != ""{
  296. nodecfg.PostDown = node.Postdown
  297. }
  298. if node.Listenport != 0{
  299. nodecfg.Port = node.Listenport
  300. }
  301. if node.Keepalive != 0{
  302. nodecfg.KeepAlive = node.Keepalive
  303. }
  304. if node.Publickey != ""{
  305. nodecfg.PublicKey = node.Publickey
  306. }
  307. if node.Endpoint != ""{
  308. nodecfg.Endpoint = node.Endpoint
  309. }
  310. if node.Password != ""{
  311. nodecfg.Password = node.Password
  312. }
  313. if node.Address != ""{
  314. nodecfg.WGAddress = node.Address
  315. }
  316. if node.Address6 != ""{
  317. nodecfg.WGAddress6 = node.Address6
  318. }
  319. if node.Postchanges != "" {
  320. nodecfg.PostChanges = node.Postchanges
  321. }
  322. if node.Dnsoff == true {
  323. nodecfg.DNS = "off"
  324. }
  325. if node.Isdualstack == true {
  326. nodecfg.IsDualStack = "yes"
  327. }
  328. if node.Isingressgateway {
  329. nodecfg.IsIngressGateway = "yes"
  330. } else {
  331. nodecfg.IsIngressGateway = "no"
  332. }
  333. if node.Localrange != "" && node.Islocal {
  334. nodecfg.IsLocal = "yes"
  335. nodecfg.LocalRange = node.Localrange
  336. }
  337. modconfig.Node = nodecfg
  338. err = Write(&modconfig, network)
  339. return err
  340. }
  341. func GetCLIConfig(c *cli.Context) (ClientConfig, error){
  342. var cfg ClientConfig
  343. if c.String("token") != "" {
  344. tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))
  345. if err != nil {
  346. log.Println("error decoding token")
  347. return cfg, err
  348. }
  349. token := string(tokenbytes)
  350. tokenvals := strings.Split(token, "|")
  351. cfg.Server.GRPCAddress = tokenvals[1]
  352. cfg.Network = tokenvals[3]
  353. cfg.Node.Network = tokenvals[3]
  354. cfg.Server.AccessKey = tokenvals[4]
  355. if len(tokenvals) > 4 {
  356. cfg.Node.LocalRange = tokenvals[5]
  357. }
  358. if c.String("grpcserver") != "" {
  359. cfg.Server.GRPCAddress = c.String("grpcserver")
  360. }
  361. if c.String("apiserver") != "" {
  362. cfg.Server.APIAddress = c.String("apiserver")
  363. }
  364. if c.String("key") != "" {
  365. cfg.Server.AccessKey = c.String("key")
  366. }
  367. if c.String("network") != "all" {
  368. cfg.Network = c.String("network")
  369. cfg.Node.Network = c.String("network")
  370. }
  371. if c.String("localrange") != "" {
  372. cfg.Node.LocalRange = c.String("localrange")
  373. }
  374. } else {
  375. cfg.Server.GRPCAddress = c.String("grpcserver")
  376. cfg.Server.APIAddress = c.String("apiserver")
  377. cfg.Server.AccessKey = c.String("key")
  378. cfg.Network = c.String("network")
  379. cfg.Node.Network = c.String("network")
  380. cfg.Node.LocalRange = c.String("localrange")
  381. }
  382. cfg.Node.Name = c.String("name")
  383. cfg.Node.Interface = c.String("interface")
  384. cfg.Node.Password = c.String("password")
  385. cfg.Node.MacAddress = c.String("macaddress")
  386. cfg.Node.LocalAddress = c.String("localaddress")
  387. cfg.Node.WGAddress = c.String("address")
  388. cfg.Node.WGAddress6 = c.String("addressIPV6")
  389. cfg.Node.Roaming = c.String("roaming")
  390. cfg.Node.DNS = c.String("dns")
  391. cfg.Node.IsLocal = c.String("islocal")
  392. cfg.Node.IsDualStack = c.String("isdualstack")
  393. cfg.Node.PostUp = c.String("postup")
  394. cfg.Node.PostDown = c.String("postdown")
  395. cfg.Node.Port = int32(c.Int("port"))
  396. cfg.Node.KeepAlive = int32(c.Int("keepalive"))
  397. cfg.Node.PublicKey = c.String("publickey")
  398. cfg.Node.PrivateKey = c.String("privatekey")
  399. cfg.Node.Endpoint = c.String("endpoint")
  400. cfg.Node.IPForwarding = c.String("ipforwarding")
  401. cfg.OperatingSystem = c.String("operatingsystem")
  402. cfg.Daemon = c.String("daemon")
  403. return cfg, nil
  404. }
  405. func GetCLIConfigRegister(c *cli.Context) (GlobalConfig, error){
  406. var cfg GlobalConfig
  407. if c.String("token") != "" {
  408. tokenbytes, err := base64.StdEncoding.DecodeString(c.String("token"))
  409. if err != nil {
  410. log.Println("error decoding token")
  411. return cfg, err
  412. }
  413. token := string(tokenbytes)
  414. tokenvals := strings.Split(token, "|")
  415. cfg.Client.ServerPrivateAddress, cfg.Client.ServerGRPCPort, err = net.SplitHostPort(tokenvals[1])
  416. if err != nil {
  417. log.Println("error decoding token grpcserver")
  418. return cfg, err
  419. }
  420. cfg.Client.ServerPublicEndpoint, cfg.Client.ServerAPIPort, err = net.SplitHostPort(tokenvals[2])
  421. if err != nil {
  422. log.Println("error decoding token apiserver")
  423. return cfg, err
  424. }
  425. cfg.Client.ServerWGPort = tokenvals[0]
  426. cfg.Client.ServerKey = tokenvals[4]
  427. if c.String("grpcserver") != "" {
  428. cfg.Client.ServerPrivateAddress = c.String("grpcserver")
  429. }
  430. if c.String("apiserver") != "" {
  431. cfg.Client.ServerPublicEndpoint = c.String("apiserver")
  432. }
  433. if c.String("key") != "" {
  434. cfg.Client.ServerKey = c.String("key")
  435. }
  436. if c.String("network") != "all" {
  437. cfg.Client.Network = c.String("network")
  438. }
  439. } else {
  440. cfg.Client.ServerPrivateAddress = c.String("grpcserver")
  441. cfg.Client.ServerPublicEndpoint = c.String("apiserver")
  442. cfg.Client.ServerKey = c.String("key")
  443. cfg.Client.Network = c.String("network")
  444. }
  445. cfg.Client.Address = c.String("address")
  446. cfg.Client.Address6 = c.String("addressIPV6")
  447. cfg.Client.PublicKey = c.String("pubkey")
  448. cfg.Client.PrivateKey = c.String("privkey")
  449. return cfg, nil
  450. }
  451. func ReadConfig(network string) (*ClientConfig, error) {
  452. if network == "" {
  453. err := errors.New("No network provided. Exiting.")
  454. return nil, err
  455. }
  456. nofile := false
  457. home := "/etc/netclient"
  458. file := fmt.Sprintf(home + "/netconfig-" + network)
  459. f, err := os.Open(file)
  460. if err != nil {
  461. nofile = true
  462. }
  463. defer f.Close()
  464. var cfg ClientConfig
  465. if !nofile {
  466. decoder := yaml.NewDecoder(f)
  467. err = decoder.Decode(&cfg)
  468. if err != nil {
  469. fmt.Println("trouble decoding file")
  470. return nil, err
  471. }
  472. }
  473. return &cfg, err
  474. }
  475. func ReadGlobalConfig() (*GlobalConfig, error) {
  476. nofile := false
  477. home := "/etc/netclient"
  478. file := fmt.Sprintf(home + "/netconfig-global-001")
  479. f, err := os.Open(file)
  480. if err != nil {
  481. nofile = true
  482. }
  483. defer f.Close()
  484. var cfg GlobalConfig
  485. if !nofile {
  486. decoder := yaml.NewDecoder(f)
  487. err = decoder.Decode(&cfg)
  488. if err != nil {
  489. fmt.Println("trouble decoding file")
  490. return nil, err
  491. }
  492. }
  493. return &cfg, err
  494. }
  495. func FileExists(f string) bool {
  496. info, err := os.Stat(f)
  497. if os.IsNotExist(err) {
  498. return false
  499. }
  500. return !info.IsDir()
  501. }