config.go 15 KB

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